gpt4 book ai didi

c# - 如果 NodaTime 使用 Duration 而 Postgres 使用 INTERVAL/Period,如何在 EF Core 中进行时间戳运算?

转载 作者:行者123 更新时间:2023-12-04 03:48:33 26 4
gpt4 key购买 nike

在我的 .NET Core 3.1 项目中,我目前正在将与时间相关的代码移至 NodaTime。

我在翻译一些查询时遇到了问题,因为在 NodaTime 中两个 Instants 之间的差异产生了一个 Duration,而在 Postgres 中两个 TIMESTAMP 之间的差异产生了一个 INTERVAL。

Npgsql 将 Instant 映射到 TIMESTAMP,但 INTERVAL 是 Period。

假设我有一个名为“Visit”的实体,它有一个 ID 和两次:“到达”和“离开”。 (这不是我的实际用例,我有几个实体有这个问题,所以这是一个最小的例子)

public class Visit
{
public int Id { get; set; }
public Instant Arrived { get; set; }
public Instant Left { get; set; }
}

现在我想找到访客停留时间少于给定时间的访问:

public async Task<List<Visit>> FindVisitsShorterThan(DbSet<Visit> dbSet, Duration duration)
{
var visits =
from visit in dbSet
where (visit.Left - visit.Arrived) < duration
select visit;
return await visits.ToListAsync();
}

如果我这样做,Npgsql 会提示类似 System.InvalidCastException: Can't write CLR type NodaTime.Duration with handler type TimestampHandler - 因为不支持持续时间。

另一方面,如果我将 Duration 转换为 Period,NodaTime 会提示,因为从它的角度来看,这种差异是 Duration,无法与 < 与 Period 进行比较。

我可以做几件事,但没有一件看起来很理想:

  • 更改实体并将“Instant Left”替换为“Period Stay”,这样我就不必在查询中进行该计算。但这仅适用于一个特定的查询 - 如果我需要“左”用于另一个查询怎么办?
  • 仅使用 LocalDateTime 而不是 Instant。不同之处在于句号,因此在 NodaTime 和 Postgres 中都可以使用。但是那样我正在改变我的实体的语义 - 我希望那些时间成为 UTC 时间戳是有原因的。 LocalDateTime 本质上意味着“TZ 未知或存储在别处”,这根本不是真的。
  • 恢复到 BCL 类型并再次开始与时区作斗争。
  • 将我的实体拆分为具有 Instants 的域类型和具有 LocalTime 的特定于 Npgsql 的 DTO 类型,并在它们之间进行一些映射。可能是最好的解决方案,但似乎没有必要。

有没有更好的办法?

最佳答案

这确实是当前 Npgsql EF 对 NodaTime 类型支持的不幸限制。

好消息是我刚刚实现了上面的内容,以及其他一些 NodaTime 算术翻译 - see this tracking issue .这将包含在下周即将发布的 EF Core 5.0 版本中 - 只需等待几天,一切都会好起来的。

关于c# - 如果 NodaTime 使用 Duration 而 Postgres 使用 INTERVAL/Period,如何在 EF Core 中进行时间戳运算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64741399/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com