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