我试图将NodaTime的OffsetDateTime
类型映射到SQL Server,但我不确定如何解决NodaTime' OffsetDateTime
之间的阻抗问题。 SQL Server的DateTimeOffset
类型。
我遇到的主要问题是让LINQ支持正常工作,因为OffsetDateTime
没有<
之类的比较运算符。系统在处理平等方面也有所不同。 NodaTime考虑时间瞬间和偏移量,而SQL Server仅考虑时间瞬间。
2015-12-24 11:18+01:00
和2015-12-24 10:18+00:00
在SQL Server中被认为是相同的,但在NodaTime中不相等。
我考虑使用ICompositeUserType
将UTC日期/时间和偏移量存储在单独的列中(类似于SQL Server 2008之前),但OffsetDateTime
没有UTC / Instant属性。因此,我无法了解如何在LINQ查询中获取date.ToInstant()
以正确映射到ICompositeUserType
中的属性。
答案 0 :(得分:6)
OffsetDateTime
应映射到SQL Server datetimeoffset
。 NHibernate通过IUserType
as described in this article对自定义类型映射的支持对于实现此功能至关重要。
虽然OffsetDateTime
未直接实施IComparable
,但您可以使用OffsetDateTime.Comparer.Instant
来比较它们。在LINQ查询中仍然可能难以使用,但这是一条值得探索的途径。
有人应该编写一个NHibernate-NodaTime集成包来简化这个过程。考虑到我之前为RavenDB和Dapper做了这个,我会考虑它。 :)
对不起,我没有更好的实际“做这个”的答案。
<强>更新强>
我开始研究这个问题,并为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。 :)