在NHibernate中使用OffsetDateTime

时间:2015-12-24 12:24:32

标签: nhibernate nodatime

我试图将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中的属性。

1 个答案:

答案 0 :(得分:6)

OffsetDateTime应映射到SQL Server datetimeoffset。 NHibernate通过IUserType as described in this article对自定义类型映射的支持对于实现此功能至关重要。

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

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

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

<强>更新

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

最终,你将无法写下:

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。 :)