LINQ + 联接,嵌套的 foreach 剃须刀输出从分组依据写出标题行

本文关键字:标题 输出 联接 嵌套 剃须刀 foreach LINQ | 更新日期: 2023-09-27 17:55:21

我有一个基本的商店模型。我有项目,项目有类别,类别有菜单。我想列出按项目类别分组的给定菜单的项目,以便它写入类别名称,然后列出它下面的项目并移动到下一个类别。我被语法打败了。请帮忙。

项目:

public class Item
{
    public int ID { get; set; }
    public string Name { get; set; }
    public double Price { get; set; }
    public int Order { get; set; }
    public bool Active { get; set; }
    public Category Category { get; set; }
}

类别:

public class Category
{
    public int ID { get; set; }
    public string Name { get; set; }
    public bool Active { get; set; }
    public int Order { get; set; }
    public Menu Menu { get; set; }
}

菜单:

public class Menu
{
    public int ID { get; set; }
    public string Name { get; set; }
    public bool Active { get; set; }
    public int Order { get; set; }
}

在控制器中,我有 linq 语句:

    var model = from i in _db.Items
                join c in _db.Categories on i.Category.ID equals c.ID
                join m in _db.Menus on c.Menu.ID equals m.ID
                where m.Name == menuName
                select i;

我很确定这不适用于选择 i,但我没有想法,这就是它的当前状态。

在我的观点中,我有:

@model IEnumerable<MyStore.Models.Item>

我已经尝试了我能想到的一切来让分组工作,但什么都没有。我什至尝试将变量设置为 currentCategoryID 并检查它是否更改然后写入类别名称,但当它点击 @item.Category.Name 时它会出错,说对象引用未设置为对象的实例。

我完全迷失了。:(

更新好的,我们让这部分工作了,现在有没有办法让这个循环更优雅?我不喜欢临时变量来检查它是否是新类别。

int currentCategory = 0;
    foreach (var item in Model)
    {
        if (!item.Category.ID.Equals(currentCategory))
        {
            <h3>@item.Category.Name</h3>
           currentCategory = item.Category.ID;
        }
        <div>
                @Html.DisplayFor(modelItem => item.Name)
            </div>
        <div>
        </div>
    }

LINQ + 联接,嵌套的 foreach 剃须刀输出从分组依据写出标题行

一般来说,

您的查询看起来不错,应该会产生预期的结果 - 前提是您没有 MenuCategory 的 null 属性。

可能是您的某些类别包含 null 作为Menu属性吗?在这种情况下,您的联接将抛出 NullReferenceException,因为您直接尝试访问c.Menu.ID - 解决方法如下:

var model = from i in Items
            join c in Categories on i.Category.ID equals c.ID
            where c.Menu !=null
            join m in Menus on c.Menu.ID equals m.ID
            where m.Name == menuName
            select i;

ItemCategory 属性存在相同的问题 - 如果可以null则必须排除这些项,因为您使用 category.ID 属性:

var model = from i in Items
            where i.Category != null
            join c in Categories on i.Category.ID equals c.ID
            where c.Menu !=null
            join m in Menus on c.Menu.ID equals m.ID
            where m.Name == menuName
            select i;

编辑以回复评论:

由于没有属性为 null,因此我们可以再次从查询中删除该部分 - 但您还需要指定在从上下文中检索实体时要具体化的相关实体。在您的情况下,您还需要相关的 Category 属性,您可以使用 Include() 指定该属性:

var model = from i in Items.Include("Category")
            join c in Categories on i.Category.ID equals c.ID
            where c.Menu !=null
            join m in Menus on c.Menu.ID equals m.ID
            where m.Name == menuName
            select i;