Запрос Linq с Take () для Mysql не добавляет ограничения к фактическому запросу - PullRequest
1 голос
/ 09 июля 2019

Я использую Net Core 2.2 с Pomelo EntityFramework с базой данных MySql.

Следующий код:

return context.SomeTable
        .OrderByDescending(item => item.ExpiredTime)
        .Where(item => item.FinishedTime.HasValue
            && item.ExpiredTime.HasValue
            && item.ExpiredTime.Value < DateTime.UtcNow
            && item.IsArchive.GetValueOrDefault(false) == false/* is null or false*/)
        .Take(500)
        .Select(i=>new ItemWrapper(i))
        .ToArray();

Возвращает следующий MySql:

SELECT `item`.`Id`, `item`.`ExpiredTime`, `item`.`FinishedTime`, 
`item`.`IsArchive`
FROM `SomeTable` AS `item`
WHERE (`item`.`FinishedTime` IS NOT NULL AND `item`.`ExpiredTime` IS NOT 
NULL) AND (`item`.`ExpiredTime` < UTC_TIMESTAMP())
ORDER BY `item`.`ExpiredTime` DESC

Похоже, что Take(500) не отражается в запросе.

Я ожидаю увидеть limit = 500 в запросе sql. Изменить 1: Я использую Select(i=>new ItemWrapper(i) для создания нового класса для объекта результата, похоже, это корень проблемы. Что я делаю не так?

1 Ответ

1 голос
/ 09 июля 2019

Это происходит потому, что вы звоните item.IsArchive.GetValueOrDefault(false) == false в Where предложении. EF.Core не может перевести этот метод в SQL, поэтому сначала он материализует все элементы, а затем пытается применить остальное к данным, полученным с сервера SQL. Попробуйте удалить это условие или переписать его. Кстати, обычно EF.Core отображает предупреждения о подобных проблемах в журнале.

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