Rehydrating fluent nhibernate configured DateTime as Kind Utc rather than Unspecified

寵の児 提交于 2019-12-29 03:37:08

问题


Is there a way in fluent nhibernate to map a DateTime to rehydrate my entity with DateTime.Kind set to Utc rather than unspecified? I'm currently persisting a DateTime that is Utc, but the Kind coming back is always Unspecified, throwing off my time.


回答1:


This isn't specific to fluent, but is fundamental to the NHibernate mapping. We use an interceptor to specify the Kind. It is similar to the approach in this blog post which lists a couple alternatives. There is also a proposed patch (NH-1135) for handling UtcDateTime and LocalDateTime natively. I'd encourage you to vote for it.

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:


As of Nhibernate 3.0, using FluentNHibernate, you can do the following:

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

No need to use interceptors anymore.




回答3:


Due to @DPeden's answer, and the comment by @Ricardo_Stuven seeming to have slight confusion, I thought I would construct this example:

Having:

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

Is the same as having: (This code is meant to be illustrative, it is NOT an example to follow)

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);
        }
    }
}

Namely, it NEVER calls .ToLocalTime(), whatever you pass into it, or get out of it, is assumed to represent localtime, it is not enforced to be, it does not recognize that the developer would ever use DateTimeKind correctly.

Similarly UtcDateTimeType never calls .ToUniversalTime()



来源:https://stackoverflow.com/questions/1547133/rehydrating-fluent-nhibernate-configured-datetime-as-kind-utc-rather-than-unspec

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!