【问题标题】:How can I express GetDate() and DateAdd() methods in EF Core and LINQ?如何在 EF Core 和 LINQ 中表达 GetDate() 和 DateAdd() 方法?
【发布时间】:2019-04-04 18:14:54
【问题描述】:

我正在使用 SQL Server 和 Entity Framework Core 2。我有以下 SQL 查询(在 SQL Server Management Studio 中)正确地为我提供了前一小时添加的测量值(到测量值表中):

SELECT id, [timestamp] 
FROM measurement 
WHERE
  dateADD(MINUTE, 60, [timestamp]) > getdate()

这很好用。但现在我想使用 EF Core 2 在 LINQ 中编写此查询。 当然我可以写如下代码:

dbContext
   .Measurement
   .Include(m => m.Section)
   .GroupBy(m => m.Section, (section, m) => new Section
    {
       Name = section.Name,
       CustomerId = section.CustomerId,
       MostRecentMeasurement = m.Max(z => z.Timestamp)
    })
   .Where(x => x.MostRecentMeasurement > DateTime.Now.AddHours(-1))
   .ToList();

但这有以下缺点:

  • DateTime.Now 无法转换为 SQL,因此将在执行不佳的客户端进行评估,
  • 客户端的时区与数据库服务器的时区不同,需要额外的复杂性和计算。

如何在 EF Core 中表达查询,使其可以完全转换为 SQL?

【问题讨论】:

  • 您使用的是哪个确切的 EF Core 版本? DateTime.Now.AddHours(-1) 在最新的 EF Core 2.2.3 中完美转换为 DATEADD(hour, -1.0E0, GETDATE())
  • 我使用的是 2.1.8。我被日志消息触发:“Microsoft.EntityFrameworkCore.Query:Warning: The LINQ expression 'where ({from Measurement z in [x] select [z].Timestamp => Max()} > DateTime.Now.AddHours( -1))' 无法翻译,将在本地进行评估。”升级到2.2.3后也是这样
  • 那么问题可能出在Max。有时间我去看看。同时,您可以验证它不会在“正常”Where 中发生(不涉及GroupBy
  • 抱歉,我无法使用提供的查询重现。我试图重建实体模型,但查询给了我“忽略包含”警告和“必须是可简化节点”异常。删除Include 并将GroupBy(m => m.Section 更改为GroupBy(m => new { m.Section.Name, m.Section.CustomerId } 允许我运行它,并且它已完全转换为SQL。因此,要找到您的代码的具体问题,我们需要minimal reproducible example,但原始问题的一般答案是GETDATE() => DateTime.NowDateAdd => DateTime.AddXyz (Xyz: HoursMinutes 等)

标签: sql-server linq entity-framework-core


【解决方案1】:

DateTime.Now.AddHours(-1) 在 EF Core 5.0.8 中完美转换为 DATEADD(hour, -1.0E0, GETDATE())。

(注意,我复制了 Ivan Stoev 的评论,因为它回答了我的类似问题。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 1970-01-01
    • 2021-02-22
    相关资源
    最近更新 更多