如何在 EF Core 和 LINQ 中表达 GetDate() 和 DateAdd() 方法?
Posted
技术标签:
【中文标题】如何在 EF Core 和 LINQ 中表达 GetDate() 和 DateAdd() 方法?【英文标题】:How can I express GetDate() and DateAdd() methods in EF Core and LINQ? 【发布时间】: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.Now
和DateAdd
=> DateTime.AddXyz
(Xyz
: Hours
,Minutes
等)
【参考方案1】:
DateTime.Now.AddHours(-1) 在 EF Core 5.0.8 中完美转换为 DATEADD(hour, -1.0E0, GETDATE())。
(注意,我复制了 Ivan Stoev 的评论,因为它回答了我的类似问题。)
【讨论】:
以上是关于如何在 EF Core 和 LINQ 中表达 GetDate() 和 DateAdd() 方法?的主要内容,如果未能解决你的问题,请参考以下文章
如何将带有 LEFT JOIN 的 SQL 转换为 EF CORE 3 LINQ