为什么EF在查询引用属性时会生成这条sql

发布于 2024-10-14 18:46:21 字数 1591 浏览 1 评论 0原文

当使用 AdventureWorks 数据库并发出此查询时:

   AdventureWorksEntities entities = new AdventureWorksEntities();
   entities.Contacts.Where(x => x.FirstName == "A" 
                               || x.FirstName == "B" 
                               || x.FirstName == "C")
                     .ToList();

将被转换为此 sql,这是最好的:

//ommited for brevity
FROM [Person].[Contact] AS [Extent1]
WHERE [Extent1].[FirstName] IN (N'A',N'B',N'C')

但是,当我发出此查询时:

entities.Employee.Where(x => x.Contact.FirstName == "A" 
                             || x.Contact.FirstName == "B" 
                             || x.Contact.FirstName == "C")
                .ToList();

我得到此 SQL:

//ommited for brevity
FROM   [HumanResources].[Employee] AS [Extent1]
INNER JOIN [Person].[Contact] AS [Extent2] ON [Extent1].[ContactID] = [Extent2].[ContactID]
LEFT OUTER JOIN [Person].[Contact] AS [Extent3] ON [Extent1].[ContactID] = [Extent3].[ContactID]
WHERE [Extent2].[FirstName] = N'A' OR [Extent3].[FirstName] IN (N'B',N'C')

为什么我得到内部和外部联接,并且 EF 正在拆分两者的交叉点在哪里?

值得注意的是,使用 contains 创建相同的 SQL:

var names = new List<string>{"A", "B", "C"};
entities.Employee.Where(x => names.Contains(x.Contact.FirstName)).ToList();

编辑:所以它似乎是一个 EF bug,我已经接受了提供解决方案的答案

编辑:打开的连接问题,它位于 此处

When using the AdventureWorks database and issuing this query:

   AdventureWorksEntities entities = new AdventureWorksEntities();
   entities.Contacts.Where(x => x.FirstName == "A" 
                               || x.FirstName == "B" 
                               || x.FirstName == "C")
                     .ToList();

Will be translated to this sql, which is the best it can:

//ommited for brevity
FROM [Person].[Contact] AS [Extent1]
WHERE [Extent1].[FirstName] IN (N'A',N'B',N'C')

However when I issue this query:

entities.Employee.Where(x => x.Contact.FirstName == "A" 
                             || x.Contact.FirstName == "B" 
                             || x.Contact.FirstName == "C")
                .ToList();

I get this SQL:

//ommited for brevity
FROM   [HumanResources].[Employee] AS [Extent1]
INNER JOIN [Person].[Contact] AS [Extent2] ON [Extent1].[ContactID] = [Extent2].[ContactID]
LEFT OUTER JOIN [Person].[Contact] AS [Extent3] ON [Extent1].[ContactID] = [Extent3].[ContactID]
WHERE [Extent2].[FirstName] = N'A' OR [Extent3].[FirstName] IN (N'B',N'C')

Why am I getting an inner and outer join and is EF splitting the where across both of them?

Of Note using contains creates the same SQL:

var names = new List<string>{"A", "B", "C"};
entities.Employee.Where(x => names.Contains(x.Contact.FirstName)).ToList();

EDIT: So it appears to be a EF bug, I've accepted the answer which provided a work around

EDIT: Opened connect issue, it's located here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

他是夢罘是命 2024-10-21 18:46:21

编写一个存储过程,它接受 TVP 作为输入参数,并让 EF 实现 SP 的结果:)

Write a Stored Procedure which accepts a TVP as input parameter and let EF materialize the results from the SP :)

梦屿孤独相伴 2024-10-21 18:46:21

看起来像是 EF 中的一个错误。

我认为问题与您检查子表中的字段有关。 EF 没有看到所有 OR 子句都引用同一个表以及该表中的相同字段。因此,它创建了复杂的连接。

尝试重写它以使用 CONTAINS 而不是 OR。

在 LINQ to SQL 中使用 contains()

Looks like a bug in EF.

I think that the problems is related to you checking against a field in a sub table. EF does not see that all the OR clauses refer to the same table and the same field in that that table. Therefore, it creates that complicated join.

Try rewriting it to use CONTAINS instead of OR.

Using contains() in LINQ to SQL

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文