我正在尝试将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属性.因此,我无法看到如何让date.ToInstant()
LINQ查询正确映射到中的属性ICompositeUserType
.
OffsetDateTime
应该映射到SQL Server datetimeoffset
.通过IUserType
本文所述的 NHibernate对自定义类型映射的支持对于实现这一点至关重要.
虽然OffsetDateTime
没有直接实现IComparable
,但您可以使用OffsetDateTime.Comparer.Instant
它们进行比较.在LINQ查询中仍然可能难以使用,但这是一条探索的途径.
有人应该写一个NHibernate-NodaTime集成包来使这更简单.考虑到我之前为RavenDB和Dapper做过这个,我会考虑它.:)
对不起,我没有更好的实际"做这个"的答案.
UPDATE
我开始研究这个问题,并成功构建了IUserType
for OffsetDateTime
,但它对比较运算符不起作用 - 因为你描述的原因.我相信解决方案涉及扩展linq提供程序,类似于本博文中描述的技术.我还没有一个完整的工作示例,但是当我这样做时,我会在这里更新.
最终,你将无法写:
session.Query().Where(x => x.SomeODT > value)
因为OffsetDateTime
没有比较运算符所以它不会编译.
相反,应该扩展LINQ提供程序以支持这样的事情:
session.Query().Where(x => OffsetDateTime.Comparer.Instant.Compare(x.SomeODT, value) > 0)
或者更干净地:
session.Query().Where(x => x.SomeODT.ToInstant() > value.ToInstant())
或者两者都有.两者都将编译,但会在LINQ提供程序中没有适当的支持时抛出异常.
第二次更新
有人打败了我.现在有一组NHibernate扩展来支持这个项目中的 Noda Time数据类型.:)