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

时间:2009-10-10 05:17:37

标签: nhibernate datetime utc

在流利的nhibernate中是否有一种方法可以映射DateTime以将DateTime.Kind设置为Utc而不是未指定来重新水化我的实体?我目前正在坚持使用Utc的DateTime,但是那种回归总是未指定,浪费我的时间。

3 个答案:

答案 0 :(得分:37)

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

Map(x => x.EntryDate).CustomType<UtcDateTimeType>();

不再需要使用拦截器。

答案 1 :(得分:12)

这不是特定于流利的,但是NHibernate映射的基础。我们使用拦截器来指定Kind。它类似于列出两个备选方案的方法in this blog post。还有proposed patch (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);
        }
    }
}

答案 2 :(得分:3)

由于@ DPeden的回答,以及@Ricardo_Stuven的评论似乎有点混乱,我想我会构建这个例子:

有:

Map(x => x.EntryDate).CustomType<LocalDateTimeType>();

与拥有相同:(此代码仅供参考,不是一个示例)

Map(x => x._hiddenEntryDate).Column("EntryDate");
Ignore(x => x.EntryDate);

///...

public class MyEntity
{
    protected virtual DateTime _hiddenEntryDate { get; set; }
    public DateTime EntryDate
    {
        get
        {
            return DateTime.SpecifyKind(_hiddenEntryDate, DateTimeKind.Local);
        }
        set
        {
            _hiddenCreated = DateTime.SpecifyKind(value, DateTimeKind.Local);
        }
    }
}

即,它永远不会调用.ToLocalTime(),无论你传入它,还是离开它,都假定代表本地时间,它不是强制执行的,它不会认识到开发人员会使用DateTimeKind正确。

同样UtcDateTimeType永远不会调用.ToUniversalTime()