在1-1过滤器上为IN过滤器生成的查询连接到父表两次

时间:2013-04-18 23:36:47

标签: entity-framework sql-server-2008-r2

我遇到此问题并使用AdventureWorks2008R2进行复制,以使其更加简单。基本上,我想过滤一个父表的IN值列表,我认为它会生成这种类型的查询 但事实并非如此。

SELECT * FROM SalesOrderDetail where EXISTS( select * from SalesOrderHeader where d.id=h.id and rowguid IN ('asdf', 'fff', 'weee' )

有关如何更改LINQ语句以仅查询Header一次的任何想法?

(忽略我在Guids上匹配的事实 - 它实际上是整数;我只是在EF中快速寻找一个1-1表,因为那是问题发生的时候我碰巧找到了这些)

var guidsToFind = new Guid[] { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid()};
AdventureWorks2008R2Entities context = new AdventureWorks2008R2Entities();
var g = context.People.Where(p => guidsToFind.Contains(p.BusinessEntity.rowguid)).ToList();

这会产生以下更昂贵的查询:

SELECT [Extent1].[BusinessEntityID] AS [BusinessEntityID], 
[Extent1].[PersonType] AS [PersonType], 
[Extent1].[NameStyle] AS [NameStyle], 
[Extent1].[Title] AS [Title], 
[Extent1].[FirstName] AS [FirstName], 
[Extent1].[MiddleName] AS [MiddleName], 
[Extent1].[LastName] AS [LastName], 
[Extent1].[Suffix] AS [Suffix], 
[Extent1].[EmailPromotion] AS [EmailPromotion], 
[Extent1].[AdditionalContactInfo] AS [AdditionalContactInfo], 
[Extent1].[Demographics] AS [Demographics], 
[Extent1].[rowguid] AS [rowguid], 
[Extent1].[ModifiedDate] AS [ModifiedDate]
FROM   [Person].[Person] AS [Extent1]
INNER JOIN [Person].[BusinessEntity] AS [Extent2] ON [Extent1].[BusinessEntityID] = [Extent2].[BusinessEntityID]
LEFT OUTER JOIN [Person].[BusinessEntity] AS [Extent3] ON [Extent1].[BusinessEntityID] = [Extent3].[BusinessEntityID]
WHERE [Extent2].[rowguid] = cast('b95b63f9-6304-4626-8e70-0bd2b73b6b0f' as uniqueidentifier) OR [Extent3].[rowguid] IN (cast('f917a037-b86b-4911-95f4-4afc17433086' as uniqueidentifier),cast('3188557d-5df9-40b3-90ae-f83deee2be05' as uniqueidentifier))

1 个答案:

答案 0 :(得分:0)

真奇怪。看起来像LINQ限制。

我现在没有系统可以尝试这个,但是如果您首先根据提供的guid获取BusinessEntityId值列表,然后获取此类人员

var g = context.People.Where(p => businessEntityIdList.Contains(p.BusinessEntityId)).ToList();

不应该有其他不必要的连接的原因。

如果可行,您可以尝试将步骤合并为一个LINQ表达式,以查看分离是否保持不变。