简体   繁体   中英

Linq query with Take() to Mysql does not add limit to actual query

I am using net core 2.2 with Pomelo EntityFramework with MySql database.

The following code:

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();

Returns the following 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

It seems like the Take(500) is not being reflected in the query.

I expect to see limit = 500 in the sql query. Edit 1: I am using Select(i=>new ItemWrapper(i) to create a new class for the result object, it seems to be the root of the issue. What am i doing wrong?

This happens because you are calling item.IsArchive.GetValueOrDefault(false) == false in Where clause. EF.Core cannot translate this method to SQL so it materializes all the items first and then tries to apply the rest to the data retrieved from SQL server. Try to remove this condition or rewrite it. BTW, usually EF.Core shows warnings for these kind of issues in the log.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM