在 .net MVC 中渲染列表的子列表

yon*_*age 2 c# asp.net-mvc razor

我仍在学习 .net MVC,也许没有正确搜索我需要找到解决方案的内容。

简而言之,我在数据库中有一个表,其结构如下:

ID    Category    Subcategory    FK
Run Code Online (Sandbox Code Playgroud)

所以每个类别可能会出现多次,每个子类别也是如此,这是该类别所独有的。

我想在视图中渲染一个菜单,如下所示:

Category 1
    Subcategory 1a
    Subcategory 1b
    Subcategory 1c
Category 2
    Subcategory 2a
    Subcategory 2b
Run Code Online (Sandbox Code Playgroud)

等等。现在在控制器中我有:

var categories = db.Category
                     .Where(oa => oa.Category != "")
                     .GroupBy(oa => new { oa.Category, oa.Subcategory })
                     .Select(oa => oa.FirstOrDefault());
Run Code Online (Sandbox Code Playgroud)

但是,我不确定如何在视图中实现我想要实现的目标。我知道我必须以某种方式遍历列表,但我不确定如何。我知道它涉及以下内容:

@foreach (var item in Model)
{
    <li>
        <a id="@item.ID" href="#">@item.Category</a>
    </li>
}
Run Code Online (Sandbox Code Playgroud)

但我只希望每个类别出现一次,然后需要所有子类别出现在父类别下。或者也许我需要更改控制器及其发送数据的方式?

小智 5

首先创建一个简单的视图模型来表示要在视图中显示的内容

public class CategoryVM
{
    public string Name { get; set; }
    public IEnumerable<string> SubCategories { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后将查询投影到该视图模型的集合并将其返回到视图

var model = db.Category.Where(x => x.Category != "")
    .GroupBy(x => x.Category).Select(x => new CategoryVM
    {
        Name = x.Key,
        SubCategories = x.Select(y => y.Subcategory)
    });
return View(model);
Run Code Online (Sandbox Code Playgroud)

并在视图中

@model IEnumerable<CategoryVM>
....
@foreach(var category in Model)
{
    <h2>@category.Name</h2>
    <ul>
        @foreach(var subCategory in category.SubCategories)
        {
            <li>@subCategory</li>
        }
    </ul>
}
Run Code Online (Sandbox Code Playgroud)