创建此查询时:
context.Orders.Where(x => context.Customers.Where(c => c.PersonID ==
10002).Select(c => c.CustomerID.Value).Contains(x.CustomerID.Value)).ToList();
我期待它创建一个这样的查询:
select * from Orders where CustomerID in (select CustomerID from Customers
Where PersonID = 10002)
但生成的查询等同于:
select * from Orders o where Exists(select 1 from Customers c where
c.PersonID = 10002 and c.CustomerID = o.CustomerID)
这是一个非常简单的查询,可以写成:
context.Orders.Where(x => x.Customer.PersonID == 10002).ToList()
但我的实际情况不可能。此外,对于这个简单的查询,执行时间并没有不同,但在更复杂的情况下,预期的查询运行得更快。
如何强制EF以我想要的方式使用查询?
答案 0 :(得分:2)
我的理论是,EF本身不支持Contains
,但支持Any
。作为一个hack,它将您的表达式转换为等效的Any
表达式,该表达式转换为Sql中的Exists
表达式。
我遇到的问题是sql查询比它需要的更麻烦(你的问题),而且我也找到了数据库无法优化的例子。
我使用的解决方法是将Contains
替换为内部Join
。所以你的例子就变成了:
from c in context.Customers
join o in context.Orders on o.CustomerId equals c.CustomerId
where c.PersonId = 10002
select o;
(抱歉,我知道你使用的是lambda表达式,但我不知道如何使用这些表达式编写联接。)