EF Core MySQL 在使用 DateTimeOffset 时使用不一致的时区

我使用带有 MySql.EntityFrameworkCore 8.0.20 的 EF Core 3.1.1。由于服务已经上线,暂时无法更新包。

当添加如下一行时,DateTimeOffset.Now 被评估在生成 SQL 查询之前,即将系统时区中的当前时间推送到数据库。 >

dbContext.Set<MyTable>().Add(new MyTable
{
    ...
    RegisteredAt = DateTimeOffset.Now
    ...
});

但是,当通过比较 DateTimeOffset 值的查询检索行时,DateTimeOffset.Now 被替换为 UTC_TIMESTAMP(),表示当前的 UTC 时间。我认为这应该是 CURRENT_TIMESTAMP()(或 NOW()),因为 DateTimeOffset.Now 在其他上下文中被视为当前本地时间。

var myTable = from m in dbContext.Set<MyTable>()
              where m.RegisteredAt < DateTimeOffset.Now
              select m;

生成的SQL查询如下:

SELECT ...,`i`.`RegisteredAt`,...
FROM `Item` AS `i`
WHERE (`i`.`BeginsAt` < UTC_TIMESTAMP())

我发现将 DateTimeOffset.Now 移动到单独的变量可以解决这个问题,但这需要我使用 DateTimeOffset.Now 查找和编辑每个 LINQ 查询。

var currentTime = DateTimeOffset.Now;
var myTable = from m in dbContext.Set<MyTable>()
              where m.RegisteredAt < currentTime
              select m;

EF Core 3.1.1 中是否有任何功能可以拦截生成的 SQL 并将 UTC_TIMESTAMP() 替换为 CURRENT_TIMESTAMP()

iCMS 回答:EF Core MySQL 在使用 DateTimeOffset 时使用不一致的时区

我发现 EF Core 3 有一个名为 interceptors 的特性,它可以用于在执行之前改变所有 SQL 查询。覆盖 DbCommandInterceptor.ReaderExecutingDbCommandInterceptor.ReaderExecutingAsync 并按如下方式编辑 SQL 查询:

public override InterceptionResult<DbDataReader>,ReaderExecuting(
    DbCommand command,CommandEventData eventData,InterceptionResult<DbDataReader> result)
{
    command.CommandText = command.CommandText.Replace("UTC_TIMESTAMP()","CURRENT_TIMESTAMP()");
    return result;
}

// Do similarly in ReaderExecutingAsync

但我不确定这是否只会对性能产生有限的影响。

本文链接:https://www.f2er.com/143400.html

大家都在问