.Net Framework Entity Framework: Как избежать внутреннего выбора? - PullRequest
0 голосов
/ 15 ноября 2018

Я использую Entity Framework для следующих целей: Получить последнюю строку, где некоторые столбцы равны X и Y. LINQ выглядит следующим образом (я также пытался переписать его как выражение «ОТ ГДЕ», среди прочего,безрезультатно):

var logEvent = Context.Set<Log>().Where(e =>
            e.Id == id && e.MessageType == messageType)
            .OrderByDescending(e => e.DateTime)
            .FirstOrDefault();

Я ожидал бы, что это сгенерирует следующее:

SELECT TOP (1) *
FROM [dbo].[Log]
WHERE [Log].[Id] = @p__linq__0
AND [Log].[MessageType] = @p__linq__1
ORDER BY [Log].[DateTime] DESC

Вместо этого он генерирует внутренний Select, который просто повторяется по всей таблице, и выбор TOP1 из упорядоченных рядов.(Я проиндексировал DateTime и Id)

SELECT TOP (1) *
    FROM ( SELECT *
        FROM [dbo].[Log] AS [Extent1]
        WHERE ([Extent1].[Id] = @p__linq__0)
        AND ([Extent1].[MessageType] = @p__linq__1)
    )  AS [Project1]
    ORDER BY [Project1].[DateTime] DESC
GO

Что вызывает этот внутренний SELECT?

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

@ Багус Теса подсказал мне правильный ответ.Спасибо всем.

Решение OrderBy() FIRST было решением.Следующий запрос LINQ генерирует ожидаемый запрос:

var logEvent = Context.Set<Log>()
.OrderByDescending(e => e.DateTime)
.FirstOrDefault(e => (e.Id == id) && e.MessageType == messageType));

Я также протестировал на случай, если мне нужно более 1 строки результата:

var importLogEvent1 = Context.Set<ImportLog>()
.OrderByDescending(e => e.DateTime)
.Where(e => (e.Id == id) && e.MessageType == messageType))
.Take(5);

Это также сгенерировало «чистый» SQL-запрос.

ПРИМЕЧАНИЕ. Как уже отмечалось, сгенерированный SQL-запрос, даже если он выглядел «плохим», вполне мог привести к столь же хорошему плану выполнения.Я не смотрел на это.

0 голосов
/ 15 ноября 2018

FirstOrDefault () является причиной перевода запроса LINQ в SELECT TOP (1) FROM (еще один выбор)

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