Результаты Entity Framework 4 и T-SQL Query не совпадают - PullRequest
1 голос
/ 18 декабря 2011

После трех лет использования Entity Framework vX сегодня я видел странное поведение 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 ]

1 голос
/ 19 декабря 2011

SQL правильный. И в этом запросе ожидается ЛЕВОЕ НАРУЖНОЕ СОЕДИНЕНИЕ.

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

1 голос
/ 19 декабря 2011

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

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 возвращает части документа, а ваш код запрашивает сущности Product? И, конечно же, для набора Продуктов возвращать дублирующиеся объекты было бы бессмысленно и неправильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...