Reputation: 89
I want to populate category and subcategory as a menu and then want to display product information by clicking on subcategory menu.
I have a model class of category, subcategory, products like this,
public class Category
{
public Category()
{
Products = new HashSet<Product>();
SubCategories = new HashSet<SubCategory>();
}
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public virtual ICollection<SubCategory> SubCategories { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
public class SubCategory
{
public SubCategory()
{
Products = new HashSet<Product>();
}
public int SubCategoryId { get; set; }
public string SubCategoryName { get; set; }
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
public class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public int CategoryId { get; set; }
public int SubCategoryId { get; set; }
public virtual Category Category { get; set; }
public virtual SubCategory SubCategory { get; set; }
}
I have subcategory item in database like this.
|CategoryName |SubCategyName
Computer HP
Computer Lenovo
Mobile Samsung
Mobile Apple
And Menu View but which is not correct:
@model IEnumerable<mTest.Models.SubCategory>
<div>
<ul>
@foreach (var category in Model)
{
<li class="active has-sub"><a href="#"><span>@category.Category.CategoryName</span></a>
<ul>
@foreach (var subcategory in Model)
{
<li class="has-sub"><a href="/Products/[email protected]"><span>@subcategory.SubCategoryName</span></a></li>
}
</ul>
</li>
}
</ul>
</div>
Which results:
|Computer=>HP
=>Lenovo
|Computer=>HP
=>Lenovo
|Mobile =>Samsung
=>Apple
|Mobile =>Samsung
=>Apple
But I want this.
|Computer=>HP
=>Lenovo
|Mobile =>Samsung
=>Apple
How to get this?
Upvotes: 3
Views: 7159
Reputation: 161
You should change your model to use a list of Categories.
@model IEnumerable<mTest.Models.Category>
...
@foreach (var category in Model)
{
...
@foreach (var subcategory in category.SubCategories)
{
...
}
...
}
Assuming each Category's SubCategories list is populated.
Upvotes: 0
Reputation: 12491
If you don't want to change your models and View you can write like this:
@foreach (var category in Model.Select(x => x.Category).Distinct())
{
<li class="active has-sub">
<a href="#"><span>@category.CategoryName</span></a>
<ul>
@foreach (var subcategory in Model.Where(x => category.Id == x.CategoryId))
{
<li class="has-sub"><a href="/Products/[email protected]"><span>@subcategory.SubCategoryName</span></a></li>
}
</ul>
</li>
}
But i recommend you to make your ViewModel
IEnumerable<mTest.Models.Category>
Type, not IEnumerable<mTest.Models.SubCategory>
. It will be just cleanier.
Like this:
@model IEnumerable<mTest.Models.Category>
<div>
<ul>
@foreach (var category in Model)
{
<li class="active has-sub"><a href="#"><span>@category.CategoryName</span></a>
<ul>
@foreach (var subcategory in category.SubCategories)
{
<li class="has-sub"><a href="/Products/[email protected]"><span>@subcategory.SubCategoryName</span></a></li>
}
</ul>
</li>
}
</ul>
</div>
Upvotes: 1