实体框架4和T-SQL查询结果不匹配

时间:2011-12-18 17:16:33

标签: sql-server entity-framework

使用Entity Framework v.X三年后,今天我看到了EF4的奇怪行为。 事实是:

在数据库AdventureWork上,执行以下命令:

var query = (ObjectQuery) context.Products.Select(p => p.ProductDocuments.Where(c => c.ProductID == p.ProductID));
Console.WriteLine(query.ToTraceString());

ToTraceSstring()显示将要执行的真实查询:

SELECT
[Project1].[ProductID] AS [ProductID],
[Project1].[C1] AS [C1],
[Project1].[ProductID1] AS [ProductID1],
[Project1].[DocumentID] AS [DocumentID],
[Project1].[ModifiedDate] AS [ModifiedDate]
FROM ( SELECT
        [Extent1].[ProductID] AS [ProductID],
        [Extent2].[ProductID] AS [ProductID1],
        [Extent2].[DocumentID] AS [DocumentID],
        [Extent2].[ModifiedDate] AS [ModifiedDate],
        CASE WHEN ([Extent2].[ProductID] IS NULL) THEN CAST(NULL AS int) ELSE 1
END AS [C1]
        FROM  [Production].[Product] AS [Extent1]
        LEFT OUTER JOIN [Production].[ProductDocument] AS [Extent2] ON ([Extent1].[ProductID] = [Extent2].[ProductID]) AND ([Extent2].[ProductID] = [Extent1].[ProductID])
)  AS [Project1]
ORDER BY [Project1].[ProductID] ASC, [Project1].[C1] ASC

从SSMS执行后,它会显示505行。

但是当我尝试从EF执行时:

var query=  context.Products.Select(p => p.ProductDocuments.Where(c => c.ProductID == p.ProductID));
Console.WriteLine(query.Count());

它只会返回504行。

在比较结果后,似乎ProductDocument中有两行具有相同的ProductID = 506,这是完全正常的。那些重复的行只被检索一次而不是预期的两次。

对这个问题有任何想法吗?

2 个答案:

答案 0 :(得分:1)

你是对的,因为对你的lambda表达的天真解释意味着你只是要求:

SELECT Products.*
FROM Products
INNER JOIN ProductDocuments
    ON ProductDocuments.ProductID = Products.ProductID

而是获得:

SELECT DISTINCT Products.*
FROM Products
INNER JOIN ProductDocuments
    ON ProductDocuments.ProductID = Products.ProductID

但是,您确定您发布的SQL是您的代码的结果,因为SQL正在返回文档的一部分,而您的代码正在请求产品实体吗?当然,对于一组产品,返回重复的实体将毫无意义且不正确。

答案 1 :(得分:1)

SQL是正确的。并且在该请求中预期LEFT OUTER JOIN。

但问题是现在查询结果不一样的原因。 ToTraceString()是否存在虚拟解释?我现在使用反射器来仔细查看导航在阅读IQueryable时的方式