Свободное автоматическое отображение NHibernate: изменение даты и времени на метку времени

Я углубляюсь (немного) в автоматизацию с помощью свободного интерфейса NHibernate. Очень хорошая вещь, но у меня возникла небольшая проблема с DateTimes. Мне нужно изменить формат данных на отметку времени, иначе NHibernate усекает миллисекунды.

Я нашел несколько источников информации, лучший из них: AutoMapping Info 1, где он изменяет имя столбца и тип свойства. Проблема в том, что, согласно этому документу, произошли изменения в автоматических приложениях.

Теперь я не могу понять, как заставить автоматическое сопоставление «изменить тип». Я попробовал следующий код, но застрял. Опять же, я просто хочу сказать автомату:

Используйте метки времени для DateTime, чтобы предотвратить усечение миллисекунд при использовании автоматического сопоставления.

У кого-нибудь есть идея? Код на данный момент:

   public class DateTimeToTimestamp : IClassConvention  
{  
    public bool Accept(IClassMap target)
    {
        return target.GetType() == typeof(DateTime);
    }

    public void Apply(IClassMap target)
    {
        throw new NotImplementedException();
    }
}

Хорошо, большое спасибо за ответ ... В этом смысле для меня достаточно комфорта. Если у меня действительно есть 3 класса, которым нужна такая точность, я могу написать его три раза. Тем более, что сопоставление всех других свойств по-прежнему отлично работает, а следующий код заменяет только одно свойство, которое я хочу ... Очень хорошо!

Если кто-то знает более общий подход, не стесняйтесь добавлять его, но пока я счастлив!

Код для моего случая был:

    public class DateTimeToTimestamp : IAutoMappingOverride<CustomTime>
{
    public void Override(AutoMap<CustomTime> mapping)
    {
        mapping.Map(x => x.ScanDate).CustomTypeIs("timestamp");
    }
}

person Christian Ruppert    schedule 21.05.2009    source источник


Ответы (3)


Вы можете переопределить определенный класс. Не знаю, как это сделать в более общем плане.

public class AlbumMappingOverride : IAutoMappingOverride<Album>
{
    public void Override(AutoMap<Album> mapping)
    {
        mapping.Map(x => x.Created).CustomSqlTypeIs("timestamp");
    }
}
person Derek Ekins    schedule 21.05.2009

Чтобы расширить ответ Дерека, чтобы сделать это на более общем уровне, вы должны использовать соглашение об автоматическом сопоставлении:

public class TimestampTypeConvention : IPropertyConvention, IPropertyConventionAcceptance
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Type == typeof (DateTime));
    }

    public void Apply(IPropertyInstance instance)
    {
        instance.CustomType<TimestampType>();
    }
}
person Daniel T.    schedule 11.09.2010
comment
Чтобы расширить поддержку DateTime, допускающего значение NULL, и узнать, как добавить соглашения в конфигурацию, см. этот ответ. Мне больше нравится реализация Apply() в этом ответе. Обратите внимание, что оба ответа также работают, если вы не используете автоматическое сопоставление, но имеете выделенные классы сопоставления. - person Manfred; 29.11.2015
comment
Вам действительно стоит использовать criteria.Expect(x => x.Type == typeof(DateTime) || x.Type == typeof(DateTime?)); - person Scott Whitlock; 14.06.2017

Ответ Дани - это тот, который следует использовать, хотя для его работы необходимо внести небольшое изменение в метод Apply (): CustomSqlType ("timestamp") -> CustomType ("Timestamp"). Я проверил это, так как только что реализовал решение в своем собственном проекте.

Примечание. Я попытался внести изменения в ответ Дэниела выше, но не смог, потому что изменение было слишком маленьким, поэтому вот исправленный код:

public class TimestampTypeConvention : IPropertyConvention, IPropertyConventionAcceptance
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Type == typeof (DateTime));
    }

    public void Apply(IPropertyInstance instance)
    {
        instance.CustomType("Timestamp");
    }
}

Вдобавок, когда я пишу новый пост, вот урезанный пример того, как вы создаете фабрику сеансов с Fluent NHibernate, которая использует соглашение, в интересах других, которые могут не знать:

var factory = Fluently.Configure()
        .Mappings(m => m.FluentMappings.Conventions.Add(new TimestampConvention()))
        .BuildSessionFactory();

Престижность этого сообщения за то, что я узнал об этом, поскольку я видел много других сообщений в сети с той же проблемой .

person Xcalibur    schedule 10.04.2012
comment
Вам действительно стоит использовать criteria.Expect(x => x.Type == typeof(DateTime) || x.Type == typeof(DateTime?)); - person Scott Whitlock; 14.06.2017