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>
}
一般来说,
您的查询看起来不错,应该会产生预期的结果 - 前提是您没有 Menu
或 Category
的 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;
Item
的 Category
属性存在相同的问题 - 如果可以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;