如何通过 LINQ 将 TimeSpan 计算转换为 SQL

Posted

技术标签:

【中文标题】如何通过 LINQ 将 TimeSpan 计算转换为 SQL【英文标题】:How to translate TimeSpan calculations to SQL via LINQ 【发布时间】:2019-06-09 05:55:29 【问题描述】:

我有一个具有 TimeSpan 属性 (Start) 和 int (Duration in minutes) 属性的实体。

我想执行一个 linq 查询,它将获取适用于以下逻辑的所有行:

Start <= DateTime.Now <= Start + Duration

我的 LINQ

from n in _context.Notifications
where n.Start <= DateTime.Now.TimeOfDay && DateTime.Now.TimeOfDay <= n.Start.Add(new TimeSpan(0, n.Duration, 0))
select n;      

转换为(取自 SQL Server Profiler)

SELECT [n].[Id], [n].[Active], [n].[Created], [n].[Day], [n].[Duration], [n].[Name], [n].[Start], [n].[Type]
FROM [Notifications] AS [n]
WHERE [n].[Start] <= CAST(GETDATE() AS time)

我从 EntityFramework Core 收到的警告是

Microsoft.EntityFrameworkCore.Query:Warning: The LINQ expression 'where (DateTime.Now.TimeOfDay 无法翻译,将在本地进行评估。

我想要的 SQL 查询是这样的

SELECT [n].[Id], [n].[Active], [n].[Created], [n].[Day], [n].[Duration], [n].[Name], [n].[Start], [n].[Type]
FROM [Notifications] AS [n]
WHERE CAST(GETDATE() AS TIME) BETWEEN [n].[Start] AND DATEADD(MINUTE, [n].[Duration], [n].[Start])

【问题讨论】:

与问题无关:您可以这样做 TimeSpan.FromMinutes(n.duration) - 对我来说似乎更具可读性。 【参考方案1】:

简单的解决方案:不要将计算作为 LINQ 查询的一部分运行。首先执行时间跨度,然后运行 ​​2 个 datetiime 实例作为参数。完成。

【讨论】:

我不明白。如何在没有StartDuration 数据的情况下进行时间跨度计算? 对不起@Dimitris,有些人在回答/投票之前没有仔细阅读问题。这是针对不同情况的标准答案,显然不适用于您的情况。【参考方案2】:

您是否研究过 EF SQL 函数?

https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.sqlserverdbfunctionsextensions?view=efcore-3.1

不幸的是,我没有看到 DateTimeOffset 和 Timespan 函数的混合,但你可能可以让那里的东西为你工作。

【讨论】:

以上是关于如何通过 LINQ 将 TimeSpan 计算转换为 SQL的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SUM 计算将 SQL 转换为 Linq

如何将 TimeSpan 序列化为 XML

从 TimeSpan 小时计算天数

LINQ to Entities 无法识别方法“System.TimeSpan Subtract(System.DateTime)”方法

在 MVC 控制器中将 Javascript 时间字符串转换为 DateTime 或 TimeSpan

将 SQL 查询转换为 LINQ/点表示法