EF6 LINQ 查询与给定本地时间戳同一天的 UTC 数据库时间戳?

问题描述 投票:0回答:1

我正在尝试编写一个 EF6 LINQ 查询,该查询采用 DateTimeOffset 并检索时间戳与给定本地日期相同的所有数据库条目。数据库的所有时间戳均为 UTC,但 DateTimeOffset 参数包含与 UTC 的本地偏移量,作为“同一天”标识的基础。


例如,假设数据库有两个时间戳分别为“2024-09-01 4PM UTC+0”和“2024-09-02 5AM UTC+0”的条目。

如果我传入的 DateTimeOffset 为“2024-09-01 11AM UTC-7”,我希望两个条目匹配:“2024-09-01 4PM UTC+0”转换为“2024-09-01 9AM UTC” -7”和“2024-09-02 5AM UTC+0”转换为“2024-09-01 10PM UTC-7”,并且两个结果的日期都与参数的日期 2024-09-01 匹配。

如果我传入“2024-08-31 9PM UTC-7”的 DateTimeOffset,则应该没有匹配项,因为将数据库时间戳转换为 UTC-7 会产生落在“2024-09-1”而不是“2024- 08-31”。请注意,此处给定的时间戳转换为“2024-09-01 4AM UTC+0”,但没有匹配项,因为本地偏移量作为基础 - 而不是 UTC。

最后,给出“2024-09-02 3AM UTC+1”的 DateTimeOffset 应该仅与时间戳为“2024-09-02 5AM UTC+0”的数据库条目匹配,因为该时间戳会转换为“2024-09-02” 6AM UTC+1”,具有匹配的 2024-09-02 日期,但“2024-09-01 4PM UTC+0”的条目转换为“2024-09-01 5PM UTC+1”并且不匹配。


像上面那样布局将使编写一个 C# 函数看起来很简单,该函数可以根据给定的 DateTimeOffset 和时间戳列表查找匹配项。但是,如果可能的话,我希望在数据库上进行所有处理,以利用索引并最大限度地减少检索的行数(即仅获取通过检查的条目)。

因此,我不能使用类似的东西:

return context.Table.Where(row => row.Timestamp.ToOffset(givenDTO.Offset).Date == givenDTO.Date).ToList();

因为 LINQ to Entities 不支持

ToOffset()
Date

我尝试过使用System.Data.Entity.DbFunctions,但是我找不到很多使用示例,所以我的结果都是错误的或者抛出异常。例如:

return context.Table.Where(row => DbFunctions.DiffDays(row.Timestamp, givenDTO) <= 1).ToList()

在给出“2024-08-31 9PM UTC-7”的第二种情况下失败。

尝试通过

DbFunctions.CreateDateTimeOffset()
为每个条目创建一个新的 DateTimeOffset 来与给定的 DateTimeOffset 进行比较,如果给定的 DateTimeOffset 的偏移量为负数,则为
givenDTO.Offset.Hours
参数传递
int? timeZoneOffset
会产生 OverflowException。


我不知道如何编写这个查询。还可能吗?

linq entity-framework-6 linq-to-entities
1个回答
0
投票

您是否可以将本地参考时间转换为 UTC 日期/时间范围,然后在查询中用作过滤器,而不是将数据库

Timestamp
值转换为本地时间进行比较?

类似:

DataTime fromUtc = givenDTO.Date - givenDTO.Date.Offset; // Not sure of the exact expression
DataTime toUtc = fromUtc.AddDays(1);

return context.Table
    .Where(row => row.Timestamp >= fromUtc && row.Timestamp < toUtc)
    .ToList();

例如,给定日期时间偏移量

2024-08-09 12:34 +0200
,我们将截断日期并调整为 UTC,产生
fromUtc = 2024-08-08 22:00
,然后为
toUtc = 2024-08-09 22:00
添加 24 小时。然后我们查询具有
Timestamp >= '2024-08-08 22:00' && Timestamp < '2024-08-09 22:00'
的行。

请注意,

toUtc
排他性。匹配值包含在结果中。

© www.soinside.com 2019 - 2024. All rights reserved.