Регидратация безводного nhibernate настроила DateTime как вид Utc, а не Unspecified

Есть ли способ свободно nhibernate отображать DateTime для регидратации моего объекта с помощью DateTime.Kind, установленного в Utc, а не неопределенного? В настоящее время я сохраняю DateTime, который является Utc, но возвращение типа всегда не указано, отбрасывая мое время.

Ответы

Ответ 1

Это не относится к беглому, но имеет фундаментальное значение для отображения 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);
        }
    }
}

Ответ 2

Начиная с Nhibernate 3.0, используя FluentNHibernate, вы можете сделать следующее:

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

Больше не нужно использовать перехватчики.

Ответ 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()