使用Nhibernate将C#DateTime映射到SQL Server datetimeoffset

使用Nhibernate将C#DateTime映射到SQL Server datetimeoffset,c#,nhibernate,C#,Nhibernate,假设您有一个非常复杂的系统,大量使用DateTime(超过1k个位置,一些助手和扩展依赖于确切的类型)。假设您决定从现在起需要存储UTC日期 我最初的想法是用DateTimeOffset替换所有DateTime类型,但这不是一项简单的任务,因为它在不同的上下文中大量使用 问题是我是否可以只更改NHiberante映射,而不必更改系统其余部分中使用的类型。或者,大规模重构是唯一的方法吗?如果您使用NHibernate Fluent自动映射,这是我的惯例: public class UtcD

假设您有一个非常复杂的系统,大量使用DateTime(超过1k个位置,一些助手和扩展依赖于确切的类型)。假设您决定从现在起需要存储UTC日期

我最初的想法是用DateTimeOffset替换所有DateTime类型,但这不是一项简单的任务,因为它在不同的上下文中大量使用


问题是我是否可以只更改NHiberante映射,而不必更改系统其余部分中使用的类型。或者,大规模重构是唯一的方法吗?

如果您使用NHibernate Fluent自动映射,这是我的惯例:

    public class UtcDateTimeConvention : IPropertyConvention, IPropertyConventionAcceptance
    {
        public void Apply(IPropertyInstance instance)
        {
            instance.CustomType<UtcDateTimeType>();
        }

        public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
        {
            criteria.Expect(x =>
                x.Property.PropertyType.Equals(typeof(DateTime)) ||
                x.Property.PropertyType.Equals(typeof(DateTime?)));
        }
    }

如果数据库始终存储UTC值,则可以将日期时间字段映射为NHibernate UtcDateTime类型,而不是常规日期时间类型。请参见示例。

NHibernate如何知道要应用的偏移量?它将如何处理历史日期的加载?如果要采用UTC,它必须贯穿整个代码库。从以下描述:•62位数字,表示自1/1/0001以来的刻度数•2位枚举,表示日期时间类型(未指定、本地或UTC),这就好像你总是可以让ConversionTcDateTimeType看起来并不完全是DateTimeOffset类型,这里可能有一些强制转换。事实上,如果你得到持久化值并对其执行ToLocalTime(),你会得到一个异常
        public static DateTime ToUserTimeZone(this DateTime utcDateTime, TimeZoneInfo currentTimeZone)
        {
            if (utcDateTime.Kind != DateTimeKind.Utc)
            {
                throw new ArgumentException("utcDateTime.Kind != DateTimeKind.Utc", "utcDateTime");
            }

            return TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, currentTimeZone);
        }

        public static DateTime? ToUserTimeZone(this DateTime? utcDateTime, TimeZoneInfo currentTimeZone)
        {
            if (utcDateTime.HasValue)
            {
                return ToUserTimeZone(utcDateTime.Value, currentTimeZone);
            }

            return null;
        }