You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF MySQL中ToQueryString生成时间减法SQL异常问题咨询

问题解答

1. ToQueryString输出的问题根源

你看到的ToQueryString输出SQL确实存在逻辑错误:在MySQL中,CURRENT_TIMESTAMP() - @__t_0这种写法不会按预期的“时间减去时长”计算。MySQL会将CURRENT_TIMESTAMP()和TIME类型变量转换成数值(比如把时间转成YYYYMMDDHHMMSS格式的数字)再做减法,结果完全不是你想要的“当前时间往前推10小时”,导致过滤条件几乎失效。

2. 正确的MySQL SQL写法

要实现“CreatedAt小于当前时间减10小时”的逻辑,正确的MySQL SQL有两种写法:

  • 使用DATE_SUB函数:
SELECT t.Id, t.CreatedAt, t.Status
FROM table1 AS t
WHERE (t.Status = 3) AND (t.CreatedAt < DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 10 HOUR));
  • 直接使用INTERVAL语法:
SELECT t.Id, t.CreatedAt, t.Status
FROM table1 AS t
WHERE (t.Status = 3) AND (t.CreatedAt < CURRENT_TIMESTAMP() - INTERVAL 10 HOUR);

如果要参数化时长,需将时长作为INTERVAL的参数传递,而非TIME类型变量,示例:

SET @__hours_0 = 10;
SELECT t.Id, t.CreatedAt, t.Status
FROM table1 AS t
WHERE (t.Status = 3) AND (t.CreatedAt < DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL @__hours_0 HOUR));

3. 为什么C#代码执行结果正确

EF Core实际执行查询时,并没有采用ToQueryString输出的错误逻辑。它会在客户端先计算出DateTime.Now - t的具体DateTime值(比如当前时间是2024-05-20 15:00:00,计算后得到2024-05-20 05:00:00),再将这个具体值作为参数传递给MySQL,实际执行的SQL类似:

SET @__nowMinusT_0 = '2024-05-20 05:00:00';
SELECT t.Id, t.CreatedAt, t.Status
FROM table1 AS t
WHERE (t.Status = 3) AND (t.CreatedAt < @__nowMinusT_0);

这种参数化方式避免了MySQL端的错误时间减法运算,因此结果正确。ToQueryString的输出只是SQL的近似表示,并未准确反映EF Core实际执行时的参数化处理逻辑。

内容的提问来源于stack exchange,提问作者Mehrdad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 18:42:36