2011-12-18 2 views
1

Спустя три года после использования Entity Framework v.X, сегодня я видел странное поведение от EF4. Дело в том, что:Результаты запроса Entity Framework 4 и T-SQL не соответствуют

На 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, что вполне нормально. Эти повторяющиеся строки извлекаются только один раз, а не дважды, как ожидалось.

Любая идея для этой проблемы?

ответ

1

Вы правильны, что наивная интерпретация ваших лямбда-выражений будет означать, вы просто просят:

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

SQL правильный. И LEFT OUTER JOIN ожидается в этом запросе.

Но вопрос в том, почему результаты запросов не совпадают. есть ли фиктивная интерпретация от ToTraceString()? Я использую теперь отражатель, чтобы посмотреть на то, как выглядит навигация при чтении IQueryable

Смежные вопросы