【问题标题】:SelectMany creates lots of SQL select statements instead of one with joinSelectMany 创建了许多 SQL 选择语句,而不是一个带有连接的语句
【发布时间】:2012-12-05 10:55:43
【问题描述】:

我正在使用SelectMany 编写查询,并检查了它在 LINQPad 中生成的 SQL。查询很简单。

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

我想为一位客户获取所有OrderItems

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

我得到了我期望的结果集,但是 SQL 对我来说真的很奇怪。有一堆选择语句。首先它选择一个客户,这没关系。然后它选择一个订单(因为这个客户只有一个),然后为之前选择的Order 中的每个OrderItem 创建一个选择...所以我得到的选择与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 真的像那样工作吗?或者我做错了什么,或者我的模型有问题?我找不到任何关于这种简单的SelectMany 应该如何转换为 SQL 的示例。

这对于小数量无关紧要,但是当客户有 100 个订单,每个订单有 200 个订单商品时,就会有 20 000 个选择...

【问题讨论】:

    标签: entity-framework linq-to-entities


    【解决方案1】:

    您应该使用以下内容进行查询(使用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() 等。

    【讨论】:

      猜你喜欢
      • 2018-06-27
      • 1970-01-01
      • 1970-01-01
      • 2016-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-31
      相关资源
      最近更新 更多