使用 Linq + 包含订购

Posted

技术标签:

【中文标题】使用 Linq + 包含订购【英文标题】:Order by with Linq + Include 【发布时间】:2013-01-06 19:04:52 【问题描述】:

我与两个实体有一对多关系:

Order:
int OrderId 
string OrderNumber
...

OrderItem:
int ItemId
int sequence
...

Product:
int ProductId
string ProductName

ProductType:
int ProductTypeid
string Title

一个Order 有多个OrderItems,每个OrderItem 有一个Product,每个Product 有一个ProductType

我想编写一个 Linq,它返回所有带有 itemsProductProductType 的订单,并且项目按序列字段排序。如何编写查询,例如以下查询?

在Order by with Linq 的帮助下,我写了这个查询:

var myOrder= db.Orders.Include("OrderItems")
         .Where(x => x.OrderId == 3)
         .Include("OrderItems.Product") 
         .Include("OrderItems.Product.ProductType") 
         .Select(o => new 
             order = o,
             orderItems = o.OrderItems.OrderBy(i => i.sequence)
         ).FirstOrDefault();

但是当它返回结果时,它不包含 Product 和 ProductType 数据。 我的错误在哪里?

【问题讨论】:

Order by with Linq的可能重复 【参考方案1】:

您需要先将所有呼叫发送至Include()。这应该有效:

var myOrder= db.Orders.Include("OrderItems")
     .Include("OrderItems.Product") 
     .Include("OrderItems.Product.ProductType") 
     .Where(x => x.OrderId == 3)
     .Select(o => new 
         order = o,
         orderItems = o.OrderItems.OrderBy(i => i.sequence)
     ).FirstOrDefault();

另外,当您有.Include("OrderItems.Product.ProductType") 时,您不需要.Include("OrderItems").Include("OrderItems.Product"),因为它将在包含产品类型的过程中包含OrderItems 及其产品。它必须这样做,否则您将无法在代码中导航到它们——它将它们附加到什么上?

在这种情况下,这似乎可以解释它:http://wildermuth.com/2008/12/28/Caution_when_Eager_Loading_in_the_Entity_Framework

您可以在不使用包含的情况下解决问题:

var query = db.Orders
.Where(x => x.OrderId == 3)
.Select(o => new 
order = o,
orderItems = o.OrderItems.OrderBy(i => i.sequence),
products = o.OrderItems.Select(i => new  i, i.Product, i.Product.ProductType )
);

您投射到输出选择中的任何内容都将自动预先加载。在某些方面,像这样的急切加载实际上是更可取的,因为您只是物化了您需要的东西,而不是完整的对象图。 (尽管在这种情况下,我们实现的内容与包含的内容相同。)

【讨论】:

每个 OrderItem 的 OrderItem 上的外键是否为非空? (即 ProductId) 另外,.Include(o => o.OrderItems.Select(oi => oi.Product.ProductType)) 有效吗? (如果您还没有引用,则需要添加对 System.Data.Entity 的引用。) OrderItem 中的 ProductId 可为 Nullable,但 OrderItems(OrderId =3) 的 productid 不为 null no .Include(o => o.OrderItems.Select(oi => oi.Product.ProductType)) 不起作用 让我们continue this discussion in chat

以上是关于使用 Linq + 包含订购的主要内容,如果未能解决你的问题,请参考以下文章

如何让LINQ根据文化订购?

LINQ to SQL:对来自订购系统的多个表的报告的聚合数据进行复杂查询

使用 Linq 仅选择最小值

Linq to Sql - 具有父表关系的双重分组

优化 LINQ 查询所需的帮助

LINQ Group By 和选择集合