Epi*_*dex 8 linq-to-entities entity-framework
我正在编写一个查询SelectMany
并检查它在LINQPad中生成的SQL.查询非常简单.
比方说,我有3个实体:Customer
,Order
,OrderItem
.OrderItem
掌握有关订购的产品和数量的信息.
我想OrderItems
为一位客户提供所有服务.
context.Customers.First().Orders.SelectMany(o=>o.OrderItems)
Run Code Online (Sandbox Code Playgroud)
我得到了我期望的结果集,但SQL对我来说真的很奇怪.有一堆选择语句.首先,它选择一个客户,这是好的.然后选择一个订单(因为这个客户只有一个),然后创建一个选择每个OrderItem
在之前选择的Order
...所以,因为有我获得尽可能多的选择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;
Run Code Online (Sandbox Code Playgroud)
我期望的是:
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
Run Code Online (Sandbox Code Playgroud)
一个选择,漂亮和干净.
难道SelectMany
真的就像那还是我做错了什么,或者也可以是错的是我的模型?我无法找到关于如何将这种简单SelectMany
转换为SQL的示例.
这对于小数字来说无关紧要,但是当一个客户有100个订单,每个订单有200个订单项目时,则会有20 000个选择...
您应该使用以下内容进行查询(以查询特定客户的订单商品someId
):
context.Customers.Where(c => c.Id == someId)
.SelectMany(c => c.Orders.SelectMany(o => o.OrderItems))
Run Code Online (Sandbox Code Playgroud)
或者 - First()
使用单个数据库查询重现行为:
context.Customers.Take(1)
.SelectMany(c => c.Orders.SelectMany(o => o.OrderItems))
Run Code Online (Sandbox Code Playgroud)
您的原始查询加载客户First
(查询1),然后延迟加载加载该Orders
客户的集合(查询2),然后延迟加载再次加载每个加载的订单项集合Order
(查询3到n).要避免所有这些多个查询,您不得在查询表达式中使用类似First()
或ToList()
等的"查询执行方法" .
归档时间: |
|
查看次数: |
3675 次 |
最近记录: |