Join LINQ到实体在实例而不是id上连接会生成SQL
有人能解释一下,为什么按实体而不是id联接会生成一些非常难看的sql,而实际上它在概念上做的事情与您认为的是一样的吗?e、 g 凭身份证 产生Join LINQ到实体在实例而不是id上连接会生成SQL,join,linq-to-entities,Join,Linq To Entities,有人能解释一下,为什么按实体而不是id联接会生成一些非常难看的sql,而实际上它在概念上做的事情与您认为的是一样的吗?e、 g 凭身份证 产生 FROM [COMPANY] AS [Extent1] INNER JOIN [ADDRESS] AS [Extent2] ON [Extent1].[CONTACT_ADDRESS_ID] = [Extent2].[CONTACT_ADDRESS_ID] 举例来说 from companyDirector in CompanyDirecto
FROM [COMPANY] AS [Extent1]
INNER JOIN [ADDRESS] AS [Extent2] ON [Extent1].[CONTACT_ADDRESS_ID] = [Extent2].[CONTACT_ADDRESS_ID]
举例来说
from companyDirector in CompanyDirectors
join contactAddress in ContactAddresses
on companyDirector.ContactAddress equals contactAddress
select new {companyDirector, contactAddress}
产生
FROM [COMPANY] AS [Extent1]
INNER JOIN [ADDRESS] AS [Extent2] ON EXISTS (SELECT
1 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable1]
LEFT OUTER JOIN (SELECT
[Extent3].[CONTACT_ADDRESS_ID] AS [CONTACT_ADDRESS_ID]
FROM [ADDRESS] AS [Extent3]
WHERE [Extent1].[CONTACT_ADDRESS_ID] = [Extent3].[CONTACT_ADDRESS_ID] ) AS [Project1] ON 1 = 1
LEFT OUTER JOIN (SELECT
[Extent4].[CONTACT_ADDRESS_ID] AS [CONTACT_ADDRESS_ID]
FROM [ADDRESS] AS [Extent4]
WHERE [Extent1].[CONTACT_ADDRESS_ID] = [Extent4].[CONTACT_ADDRESS_ID] ) AS [Project2] ON 1 = 1
WHERE [Project1].[CONTACT_ADDRESS_ID] = [Extent2].[CONTACT_ADDRESS_ID]
)
在我看来,这是非常低效的,迫使你进入身份证途径。为什么它要做两次左连接,更不用说一次了???我不能说出ADO.NET团队的想法或代码。尽管如此,我看到了两个可能的问题:
ContractAddresses
中的基础表中的Id
字段,或者可能仅在实体模型中,无法定义为主键。我有点怀疑这是个问题,但值得仔细检查equals
关键字可能没有很好的方法来比较联接中两个对象之间的相等性。在快速的web搜索中,我没有找到equals
用于比较的确切内容,但让我相信equals
和GetHashCode
方法都涉及其中(即使不涉及组合键)。如果您只是使用默认的object.Equals
继承方法,Linq提供程序必须以某种方式找出引用等式,我想这可能会导致一些奇怪的结果不过,我确实喜欢@Craig Stuntz在评论中提出的解决方案。此外,您可能需要为较长的查询获取一个执行计划,以查看它是否真的像看上去的那样糟糕;查询优化器可能比代码所显示的做得更好。最后,对于我来说,EF仍然缺乏在广阔的世界中执行所需的成熟度和功能。因此,我放弃了它,转而选择了NHibernate,它可以生成简单漂亮且经过优化的SQL。即使这个问题非常好,我们在这里也很难回答。这是ADO.NET团队的问题。如果ADO.NET团队没有订阅这些关键字,他们需要在某人的十字准线中:)FWIW,我不会写任何一个。我将从companyDirector中的companyDirector从companyDirector中的contactAddress写入
。ContactAddresses选择新的{companyDirector,contactAddress}
,它应该可以正常工作,并且不需要了解DB架构即可写入。
FROM [COMPANY] AS [Extent1]
INNER JOIN [ADDRESS] AS [Extent2] ON EXISTS (SELECT
1 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable1]
LEFT OUTER JOIN (SELECT
[Extent3].[CONTACT_ADDRESS_ID] AS [CONTACT_ADDRESS_ID]
FROM [ADDRESS] AS [Extent3]
WHERE [Extent1].[CONTACT_ADDRESS_ID] = [Extent3].[CONTACT_ADDRESS_ID] ) AS [Project1] ON 1 = 1
LEFT OUTER JOIN (SELECT
[Extent4].[CONTACT_ADDRESS_ID] AS [CONTACT_ADDRESS_ID]
FROM [ADDRESS] AS [Extent4]
WHERE [Extent1].[CONTACT_ADDRESS_ID] = [Extent4].[CONTACT_ADDRESS_ID] ) AS [Project2] ON 1 = 1
WHERE [Project1].[CONTACT_ADDRESS_ID] = [Extent2].[CONTACT_ADDRESS_ID]
)