SelectMany创建了许多SQL select语句,而不是带有join的语句

时间:2012-12-05 10:55:43

标签: entity-framework linq-to-entities

我正在用SelectMany编写一个查询,并检查它在LINQPad中生成的SQL。查询非常简单。

假设我有3个实体:CustomerOrderOrderItemOrderItem包含有关订购的产品和数量的信息。

我希望为一位客户提供所有OrderItems

context.Customers.First().Orders.SelectMany(o=>o.OrderItems)

我得到了我期望的结果集,但SQL对我来说真的很奇怪。有一堆选择语句。首先,它选择一个客户,这是好的。然后它选择一个订单(因为该客户只有一个订单),然后为之前选择的OrderItem中的每个Order创建一个选择...所以我得到的选择数与{{1}一样多选定OrderItems的+ Orders。所以它看起来像:

Customer

我期望的是:

select top 1 from Customers;

select * from Orders where CustomerID = @cID;

select * from OrderItems where OrderID = @o1;
select * from OrderItems where OrderID = @o2;
select * from OrderItems where OrderID = @o3;
select * from OrderItems where OrderID = @o4;

一个选择,漂亮和干净。

select oi.* from OrderItems oi join Orders o on o.OrderID = oi.OrderId join Customers c on c.CustomerID = o.CustomerID where c.CustomerID = @someID 是否真的像那样,或者我做错了什么,或者我的模型可能有问题?我无法找到关于如何将这种简单SelectMany转换为SQL的示例。

这对于小数字来说无关紧要,但是当一个客户有100个订单,每个订单包含200个订单项目时,则会有20 000个选择...

1 个答案:

答案 0 :(得分:9)

您应该使用以下内容进行查询(使用someId查询特定客户的订单商品):

context.Customers.Where(c => c.Id == someId)
    .SelectMany(c => c.Orders.SelectMany(o => o.OrderItems))

或 - 使用单个数据库查询重现First()的行为:

context.Customers.Take(1)
    .SelectMany(c => c.Orders.SelectMany(o => o.OrderItems))

原始查询使用First(查询1)加载客户,然后延迟加载加载该客户的Orders集合(查询2),然后再次延迟加载为每个加载的Order加载订单商品集合(查询3到n)。要避免所有这些多个查询,您不得在查询表达式中使用First()ToList()等“查询执行方法”。