19

有没有办法在流利的 nhibernate 中映射一个 DateTime 来重新水化我的实体,并将 DateTime.Kind 设置为 Utc 而不是未指定?我目前坚持使用 Utc 的 DateTime,但返回的 Kind 总是未指定,从而浪费了我的时间。

4

3 回答 3

38

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

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

不再需要使用拦截器。

于 2011-05-25T02:34:12.037 回答
13

这不是 Fluent 特有的,而是 NHibernate 映射的基础。我们使用拦截器来指定种类。它类似于这篇博客文章中列出了几个替代方案的方法。还有一个提议的补丁 (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);
        }
    }
}
于 2009-10-26T16:54:50.643 回答
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()

于 2014-07-10T22:57:23.167 回答