如何通过 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 实例作为参数。完成。
【讨论】:
我不明白。如何在没有Start
和Duration
数据的情况下进行时间跨度计算?
对不起@Dimitris,有些人在回答/投票之前没有仔细阅读问题。这是针对不同情况的标准答案,显然不适用于您的情况。【参考方案2】:
您是否研究过 EF SQL 函数?
https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.sqlserverdbfunctionsextensions?view=efcore-3.1
不幸的是,我没有看到 DateTimeOffset 和 Timespan 函数的混合,但你可能可以让那里的东西为你工作。
【讨论】:
以上是关于如何通过 LINQ 将 TimeSpan 计算转换为 SQL的主要内容,如果未能解决你的问题,请参考以下文章
LINQ to Entities 无法识别方法“System.TimeSpan Subtract(System.DateTime)”方法