我正在尝试将 NodaTime 的 OffsetDateTime 类型映射到 SQL Server,但我不确定如何解决 NodaTime 的 OffsetDateTime 和 SQL Server 的 DateTimeOffset 类型之间的阻抗。

我遇到的主要问题是让 LINQ 支持正常工作,因为 OffsetDateTime 没有比较运算符,例如 < 。这些系统在处理平等的方式上也有所不同。 NodaTime 同时考虑时间和偏移量,而 SQL Server 只考虑时间。
2015-12-24 11:18+01:002015-12-24 10:18+00:00 在 SQL Server 中被视为相等,但在 NodaTime 中不相等。

我考虑使用 ICompositeUserType 将 UTC 日期/时间和偏移量存储在单独的列中(类似于 SQL Server 2008 之前),但 OffsetDateTime 没有 UTC/Instant 属性。因此,我看不到如何在 LINQ 查询中获取 date.ToInstant() 以正确映射到 ICompositeUserType 中的属性。

最佳答案

OffsetDateTime 应该映射到 SQL Server datetimeoffset 。 NHibernate 通过 IUserType as described in this article 对自定义类型映射的支持对于完成这项工作至关重要。

虽然 OffsetDateTime 不直接实现 IComparable ,但您可以使用 OffsetDateTime.Comparer.Instant 来比较它们。这在 LINQ 查询中可能仍然难以使用,但它是一种探索途径。

有人可能应该编写一个 NHibernate-NodaTime 集成包来简化这个过程。考虑到我之前已经为 RavenDBDapper 做过这件事,我会考虑它。 :)

对不起,我没有更好的实际“做这个”的答案给你。

更新

我开始研究这个,并成功地为 IUserType 构建了一个 OffsetDateTime ,但它不适用于比较运算符 - 因为你描述的原因。我相信该解决方案涉及扩展类似于 in this blog post 描述的技术的 linq 提供程序。我还没有一个完整的工作示例,但我会在这里更新。

最终,您将无法编写:

session.Query<Foo>().Where(x => x.SomeODT > value)

因为 OffsetDateTime 没有比较运算符,所以它不会编译。

相反,应该扩展 LINQ 提供程序以支持以下内容:
session.Query<Foo>().Where(x => OffsetDateTime.Comparer.Instant.Compare(x.SomeODT, value) > 0)

或者也许更干净:
session.Query<Foo>().Where(x => x.SomeODT.ToInstant() > value.ToInstant())

或者两者兼而有之。两者都会编译,但会在 LINQ 提供程序中没有适当支持的情况下抛出异常。

第二次更新

有人打败了我。现在有一组 NHibernate 扩展来支持 Noda Time 数据类型 in this project 。 :)

关于nhibernate - 在 NHibernate 中使用 OffsetDateTime,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34452792/

10-11 02:11