将流畅的nhibernate配置为DateTime为Kind Utc而不是Unspecified

Arn*_*sen 17 nhibernate datetime utc

有没有一种流畅的nhibernate映射DateTime来重新水化我的实体,DateTime.Kind设置为Utc而不是未指定?我目前正在坚持使用Utc的DateTime,但是Kind返回时总是未指定,浪费我的时间.

Dav*_*den 37

从Nhibernate 3.0开始,使用FluentNHibernate,您可以执行以下操作:

Map(x => x.EntryDate).CustomType<UtcDateTimeType>();
Run Code Online (Sandbox Code Playgroud)

无需再使用拦截器.

  • 注意事项:`UtcDateTimeType`强制DateTimeKind为Utc.如果您保存当地时间,比如13:30 UTC-3,那么它将加载时间为13:30 UTC(没有偏移).我建议使用`ToUniversalTime()`手动将所有本地时间转换为Utc,或者实现"CustomUtcDateTimeType`"以自动管理这种情况. (3认同)
  • 我怀疑我之前评论中描述的行为是数据库特定的.我最初使用SQLite,就像我一直用于原型设计,但改用SQL Server使这种奇怪的行为消失了.在单元测试期间在内存中使用SQLite时仍然存在问题. (2认同)
  • @Impero如果你将DateTimeFormat = Ticks放在连接字符串中,它将起作用.但是,这会将不好的部分移动到sqlite数据库中,因为所有DateTimes都将保存为ticks.如果你只使用sqlite进行单元测试,这就足够了. (2认同)

g .*_*g . 12

这不是特定于流畅的,但是NHibernate映射的基础.我们使用拦截器来指定Kind.它与此博客文章中的方法类似,列出了几个替代方案.还有一个建议的补丁(NH-1135)用于本地处理UtcDateTime和LocalDateTime.我鼓励你投票支持它.

public class InterceptorBase : EmptyInterceptor
{
    public override bool OnLoad(object entity, object id, object[] state,
        string[] propertyNames, IType[] types)
    {
        ConvertDatabaseDateTimeToUtc(state, types);
        return true;
    }

    private void ConvertDatabaseDateTimeToUtc(object[] state, IList<IType> types)
    {
        for (int i = 0; i < types.Count; i++)
        {
            if (types[i].ReturnedClass != typeof(DateTime))
                continue;

            DateTime? dateTime = state[i] as DateTime?;

            if (!dateTime.HasValue)
                continue;

            if (dateTime.Value.Kind != DateTimeKind.Unspecified)
                continue;

            state[i] = DateTime.SpecifyKind(dateTime.Value, DateTimeKind.Utc);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)