在 LINQ to Entities 中正确比较没有时间的 DatetimeOffset

Posted

技术标签:

【中文标题】在 LINQ to Entities 中正确比较没有时间的 DatetimeOffset【英文标题】:Properly compare DatetimeOffset without Time in LINQ to Entities 【发布时间】:2017-03-16 05:24:47 【问题描述】:

我一直在测试一些方法来比较 LINQ to Entities 中的两个 DateTimeOffset 对象,但我不确定哪一个是最有效的以及实际正确的方法。

我尝试了以下方法:

SomeTable.Where(a => DbFunctions.TruncateTime(a.StartUtc) <= intendedDate && DbFunctions.TruncateTime(a.EndUtc) >= intendedDate);

它为比较生成了这个大而复杂的查询:

((convert (datetimeoffset, convert(varchar(255), [Extent1].[StartUtc], 102) + ' 00:00:00 ' +  Right(convert(varchar(255), [Extent1].[StartUtc], 121), 6)  ,  102)) <= @p__linq__1) AND ((convert (datetimeoffset, convert(varchar(255), [Extent1].[EndUtc], 102) + ' 00:00:00 ' +  Right(convert(varchar(255), [Extent1].[EndUtc], 121), 6)  ,  102)) >= @p__linq__2)

还尝试了DiffDays,它生成了更具可读性的查询

((DATEDIFF (day, [Extent1].[StartUtc], '2016-11-01 00:00:00 -02:00')) >= 0) AND ((DATEDIFF (day, '2016-11-01 00:00:00 -02:00', [Extent1].[EndUtc])) >= 0)

但是这个查询需要考虑时间,我不能这样做。

我不是专家,但对于这么简单的要求,第一个查询似乎真的很长而且很复杂。当我应该使用原始 SQL 而不是 LINQ 和 EF 时,是这种情况吗?我无法决定哪种方法最有效。 我觉得CAST('2016-11-02 00:00:00 AM -02:00' AS DATE) 比 EF 生成的查询更简单,因此性能更高。

这里最好的做法是什么?

【问题讨论】:

使用“日期”属性将时间截断到午夜,然后获取日期之间的差异。 DateTime 以双精度形式存储在计算机中,整数部分是自 1900 年 1 月 1 日以来的天数,小数部分是当前时间/24(即 3.5 小时/24 小时)。 @jdweng Date 属性不受 L2E 支持 【参考方案1】:

要不要对包含的时间感到棘手?

var cmpStartDate = intendedDate.AddDays(1);

var ans = SomeTable.Where(a => a.StartUtc < cmpStartDate && a.EndUtc > intendedDate.Subtract(TimeSpan.FromTicks(1)));

【讨论】:

以上是关于在 LINQ to Entities 中正确比较没有时间的 DatetimeOffset的主要内容,如果未能解决你的问题,请参考以下文章

LINQ to Entities区分大小写比较

VB.Net Linq to Entities Null 比较 - “啥都没有”或“= 啥都没有”?

LINQ to Entities 无法识别该方法

LINQ to Entities 无法识别该方法:LastOrDefault [重复]

在 LINQ to Entities 中批量删除

Linq to Entities 和 LEFT OUTER JOIN 问题与 MANY:1 关系