【问题标题】:Linq query with Take() to Mysql does not add limit to actual query使用 Take() to Mysql 的 Linq 查询不会对实际查询添加限制
【发布时间】:2019-07-09 10:29:19
【问题描述】:

我正在使用带有 Pomelo EntityFramework 和 MySql 数据库的 net core 2.2。

以下代码:

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) 似乎没有反映在查询中。

我希望在 sql 查询中看到 limit = 500。 编辑1: 我正在使用Select(i=&gt;new ItemWrapper(i) 为结果对象创建一个新类,这似乎是问题的根源。 我做错了什么?

【问题讨论】:

  • 看来是因为你打电话给item.IsArchive.GetValueOrDefault(false) == false。 EF 无法将此函数转换为 SQL,因此它会具体化它之前的所有内容,然后尝试继续将其余部分应用于从 SQL 服务器检索到的数据。尝试删除此条件或重写它。通常 EF.Core 在运行实际查询之前会在日志中显示警告。
  • 在 MySQL 中,您应该期望 limit 0, 500 而不是 limit = 500。
  • @AlexeyAndrushkevich 你的回答解决了问题
  • @ErezBenHarush 将我的评论转换为答案。

标签: mysql entity-framework asp.net-core entity-framework-core


【解决方案1】:

发生这种情况是因为您在 Where 子句中调用了 item.IsArchive.GetValueOrDefault(false) == false。 EF.Core 无法将此方法转换为 SQL,因此它首先实现所有项目,然后尝试将其余项目应用于从 SQL 服务器检索的数据。尝试删除此条件或重写它。顺便说一句,EF.Core 通常会在日志中显示此类问题的警告。

【讨论】:

    猜你喜欢
    • 2014-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多