Dynamic menu from database in Asp.Net MVC - c#

I'm a beginner and I want to display menu on the left side like This Website and when user clicks on any Category Name or its Sub Category Name I want to display Products related to the clicked category.
I've created 4 tables in my database.
Category
CategoryId(pk), CategoryName, Description, Icon
SubCategory
SubCategoryId(pk), SubCategoryName, Description, Icon,CategoryId(fk)
SubSubCategory
SubSubCategoryId(pk), SubSubCategoryName, Description, Icon, SubCategoryId(fk)
Products
ProductId(pk), Name, Price, Description, CategoryId(fk), SubCategoryId(fk), SubSubCategoryId(fk)
Category.cs Model
public partial class Category
{
public Category()
{
Products = new HashSet<Product>();
SubCategories = new HashSet<SubCategory>();
}
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public string Description { get; set; }
public string Icon{ get; set; }
public virtual ICollection<Product> Products { get; set; }
public virtual ICollection<SubCategory> SubCategories { get; set; }
}
SubCategory.cs
public partial class SubCategory
{
public SubCategory()
{
Products = new HashSet<Product>();
SubSubCategories = new HashSet<SubSubCategory>();
}
[Key]
public int SubCategoryId { get; set; }
public string SubCategoryName { get; set; }
public int? CategoryId { get; set; }
public string Description { get; set; }
public string Icon{ get; set; }
public virtual Category Category { get; set; }
public virtual ICollection<Product> Products { get; set; }
public virtual ICollection<SubSubCategory> SubSubCategories { get; set; }
}
SubSubCategory.cs
public partial class SubSubCategory
{
public SubSubCategory()
{
Products = new HashSet<Product>();
}
[Key]
public int SubSubCategoryId { get; set; }
public string SubSubCategoryName { get; set; }
public int? SubCategoryId { get; set; }
public string Description { get; set; }
public string Image { get; set; }
public virtual ICollection<Product> Products { get; set; }
public virtual SubCategory SubCategory { get; set; }
}
Product.cs
public partial class Product
{
public int ProductId { get; set; }
public int? CategoryId { get; set; }
public int? SubCategoryId { get; set; }
public int? SubSubCategoryId { get; set; }
public string Name { get; set; }
[AllowHtml]
public string Description { get; set; }
public decimal? Price { get; set; }
}

You should try to first load the whole collection that you want to use in the current view.
Then use lambda expressions or predicates to sort the data into categories e.g
var list = wholeList.Where(i => i.category == "{category-name}");
then load this list to the view templates.
This method is both fast and convenient

On Click of Category, SubCategory, Sub Sub Category,
You should try below MVC way to load partials. Use appropriate overload of this.
#Ajax.ActionLink( ....)
Remember to use targetId in which element your called partial will load.
Your Layout must include jquery and jquery.unobtrusive-ajax. (jquery version must be higher than 1.9)

Related

cannot map entities using entity framework core

I have in database two tables: product, supplier
I want the entity framework to define the supplier of each product
I am getting data successfully for two tables but the supplier in the product table is null.
Also, the products collection in the supplier table is null.
this is my product class:
public class Product
{
public int id { get; set; }
[Column("Productname", TypeName = "ntext")]
public string Name { get; set; }
public decimal UnitPrice { get; set; }
public bool isDiscounted { get; set; }
public int quantity { get; set; }
public int SupplierId { get; set; }
[ForeignKey("SupplierId")]
public Supplier supplier { get; set; }
}
this is the class of supplier:
public class Supplier
{
public int Id { get; set; }
public string CompanyName { get; set; }
public string ContactName { get; set; }
public string ContactTitle { get; set; }
public string city { get; set; }
public string country { get; set; }
public string phone { get; set; }
public string Fax { get; set; }
public List<Product> Products { get; set; }
}
context class:
public class DbConext : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<Supplier> Suppliers { get; set; }
public DbConext(DbContextOptions<DbConext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>().ToTable("Product");
modelBuilder.Entity<Supplier>().ToTable("Supplier");
modelBuilder.Entity<Product>().HasKey("id");
modelBuilder.Entity<Supplier>().HasKey("Id");
modelBuilder.Entity<Product>().HasOne(p => p.supplier).WithMany(s => s.Products).HasForeignKey(p => p.SupplierId);
}
}
This article might help.
You should use .Include() to load any related properties.
minimum you need is to initialize the list
public class Supplier
{
public int Id { get; set; }
public string CompanyName { get; set; }
public string ContactName { get; set; }
public string ContactTitle { get; set; }
public string city { get; set; }
public string country { get; set; }
public string phone { get; set; }
public string Fax { get; set; }
public List<Product> Products { get; set; }
public Supplier() {
this.Products = new List<Product>();
}
}

Code First : Unable to create 1 to many relationship. Creates 0...1 to many instead

Customer
public class Customer
{
public Customer()
{
Addresses = new List<Address>();
Reviews = new List<Review>();
Products = new List<Product>();
}
[Key]
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Password { get; set; }
public Address DefaultAddress { get; set; }
public int DefaultAddressId { get; set; }
public List<Address> Addresses { get; set; }
public List<Review> Reviews { get; set; }
public List<Product> Products { get; set; }
}
Product
public class Product
{
public Product()
{
Reviews = new List < Review >();
}
public int Id { get; set; }
public Category Category { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Specification { get; set; }
public List<Review> Reviews { get; set; }
public List<Customer> Customers { get; set; }
}
Review
public class Review
{
public int Id { get; set; }
public string Text { get; set; }
public int Stars { get; set; }
[Required]
public int ProductId { get; set; }
[Required]
public string CustomerId { get; set; }
}
}
Generated model
I want the relationship between Review and Customer to 1 to many not 0..1 to many. Each review must belong to one customer. I don't understand how the relationship is mapped properly for Review - Product but not for the customer.
i only used Customer and Review models since those are the once you wanted an answer.
Following is the your model classes should be.
public class Customer
{
public Customer()
{
Reviews = new HashSet<Review>();
}
[Key]
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Password { get; set; }
public ICollection<Review> Reviews { get; set; }
}
public class Review
{
public int Id { get; set; }
public string Text { get; set; }
public int Stars { get; set; }
[Required]
public int ProductId { get; set; }
[Required]
public string CustomerId { get; set; }
[ForeignKey("CustomerId")]
public Customer Customer { get; set; }
}
this way you can have customers Review collection and cast it in to a list if you want.use Include() method in your linq query to lazy load the customers review collection.
for an example:
var customer = dbContext.Customer.Include("Reviews").where(x => x.Email == "john#gmail.com").FirstOrDefault();

select multiple column from include table in LINQ

My question is about how can i select some one-two column from those tables are included and at the end when i am selecting as list it is returning list of parent object but child are contain those column i mention to select?
var testq = _db.Homes
.Include(x => x.Indexs.Cities.Proviences.Regions)
.Include(x => x.Images)
.Select(x => new Homes {
Images = x.Images,
Address = x.Address,
Indexs.Cities.Proviences.Regions =
x.Indexs.Cities.Proviences.Regions.Name });
At the end I need to have list of home model (List) and just images and Address and region name have value and important just those are selected from database not all infromation in the tables. I am trying to make a query with better performance
Edit Add Models
public partial class dbContext : DbContext
{
public virtual DbSet<City> Cities { get; set; }
public virtual DbSet<Province> Provinces { get; set; }
public virtual DbSet<Region> Regions { get; set; }
public virtual DbSet<Index> Indexs { get; set; }
public virtual DbSet<Home> Homes { get; set; }
public virtual DbSet<Images> Imageses { get; set; }
}
public partial class Home
{
public Home()
{
Imageses = new HashSet<Images>();
}
[Key]
public int IDHome { get; set; }
[Required]
[StringLength(5)]
public string Cap { get; set; }
[Required]
[StringLength(10)]
public string Number { get; set; }
[Required]
[StringLength(50)]
public string Address { get; set; }
....
public virtual Index Indexs { get; set; }
public virtual ICollection<Images> Imageses { get; set; }
}
public class Index
{
public int ID { get; set; }
public int IDHome { get; set; }
....
public virtual City Cities { get; set; }
}
public partial class City
{
[Key]
public int ID { get; set; }
public int IDProvincia { get; set; }
public decimal Latitudine { get; set; }
public decimal Longitudine { get; set; }
[Required]
[StringLength(100)]
public string Name { get; set; }
....
public virtual Province Provinces { get; set; }
}
public partial class Province
{
[Key]
public int ID { get; set; }
public int IDRegione { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[Required]
[StringLength(3)]
public string Init { get; set; }
...
public virtual Region Regions { get; set; }
}
public partial class Region
{
[Key]
public int ID { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
public DateTime DataInsert { get; set; }
...
}
public class Images
{
public int ID { get; set; }
public string Path { get; set; }
...
}
absolutely tables have more column just add here as example
you have to define a new type with the fields you need, or use an anonymous type.
.Select(x => new {
Images = x.Images,
Address = x.Address,
Indexs.Cities.Proviences.Regions =
x.Indexs.Cities.Proviences.Regions.Name });

Display multi level list

I have two model classes
public class Genre
{
[Key]
public int GenreId { get; set; }
public string GenreName { get; set; }
public virtual ICollection<Movie> Movies { get; set; }
}
and
public class Movie
{
[Key]
public int MovieId { get; set; }
public string MovieName { get; set; }
public string MovieDirector { get; set; }
public int MovieYear { get; set; }
public string MovieDesc { get; set; }
public DateTime CreationDate { get; set; }
public int GenreRefId { get; set; }
[ForeignKey("GenreRefId")]
public virtual Genre Genre { get; set; }
}
I know how to display a list of these objects on their own but my project requires that I list:
Each genre + the top 5 newest movies added to the list
I'm not even sure where to begin. Since you cannot use two models in a view... how do i gather and display both lists?
any help is much appreciated!

The specified type member 'Product' is not supported in LINQ to Entities

I'm getting the error 'Product' is not supported in LINQ to Entities whilst using cartItems.Product.UnitCost when trying to get the total of the basket.
public decimal GetTotal()
{
//Multiply price by count of item to get price for each item in cart and them sum all prices up
decimal? total = (from cartItems in db.ShoppingBaskets where cartItems.BasketID == ShoppingCartID select (int?)cartItems.BasketQuantity * cartItems.Product.UnitCost).Sum();
return total ?? decimal.Zero;
}
I then tried splitting the query up to see if this would fix the problem
int? quantity = (from cartItems in db.ShoppingBaskets where cartItems.BasketID == ShoppingCartID select (int?)cartItems.BasketQuantity).Sum();
decimal? price = (from cartItems in db.ShoppingBaskets where cartItems.BasketID == ShoppingCartID select cartItems.Product.UnitCost).Sum();
I get the same problem with the second separate query with 'Product'.
Product Class
public partial class Product
{
public Product()
{
this.OrderCheckouts = new HashSet<OrderCheckout>();
this.ProductReviews = new HashSet<ProductReview>();
}
public int ProductID { get; set; }
public int CategoryID { get; set; }
public int ManufacturerID { get; set; }
public string ProductName { get; set; }
public string ProductCode { get; set; }
public decimal UnitCost { get; set; }
public int UnitQuantity { get; set; }
public string ProductDescription { get; set; }
public string ProductImage { get; set; }
public virtual Category Category { get; set; }
public virtual Manufacturer Manufacturer { get; set; }
public virtual ICollection<OrderCheckout> OrderCheckouts { get; set; }
public virtual ICollection<ProductReview> ProductReviews { get; set; }
}
ShoppingBasket Class
public partial class ShoppingBasket
{
public int CartID { get; set; }
public string BasketID { get; set; }
public int BasketQuantity { get; set; }
public int ProductID { get; set; }
public virtual Product Product { get; set; }
}
Could someone explain the problem more clearly and how I can solve this? Thanks!
I think it's because Entity Framework hasn't fully created the relationship between ShoppingBasket and Product. Try adding:
public virtual ICollection<ShoppingBasket> ShoppingBaskets { get; set; }
to the Product class.

Categories

Resources