0

我遇到了这个问题,并用 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))
4

1 回答 1

0

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

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

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

不再有额外不必要的连接的理由。

如果可行,您可以尝试将 to 步骤组合到一个 LINQ 表达式中,以查看分隔是否保持不变。

于 2013-04-19T00:17:29.683 回答