2

当我创建此查询时:

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 以我想要的方式使用查询?

4

1 回答 1

2

我的理论是 EF 本身并不支持Contains,但它确实支持Any。作为一种技巧,它将您的表达式转换为等效的Any表达式,该表达式转换为ExistsSql 中的表达式。

我对这种方法的问题是 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 表达式,但我不确定如何使用这些表达式编写连接)。

于 2014-06-25T18:24:44.863 回答