Перечисление в целочисленное отображение, вызывающее обновления при каждом сбросе - PullRequest
22 голосов
/ 20 августа 2010

Я пытаюсь сопоставить свойство enum (экземпляр System.DayOfWeek) в моей модели с целочисленным полем базы данных. Другие свойства перечисления в модели должны быть сопоставлены со строками, поэтому я не хочу определять соглашение.

Я понимаю, что это должно быть возможно при использовании беглого отображения, например:

Map(x => x.DayOfWeek).CustomType<int>();

и действительно, на первый взгляд, это работает.

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

Чтобы выяснить, что вызывает этот сброс, я настроил IPreUpdateEventListener и проверил OldState и State объекта. Смотрите прикрепленное изображение. В OldState соответствующим объектом является int, тогда как в State это DayOfWeek.

Если я использую отображение HBM XML без указания атрибута типа, эта проблема не возникает.

Итак ...

Это ошибка или недостаток в GenericEnumMapper? Есть ли способ сообщить FNH-сопоставлению не указывать атрибуты типа в сгенерированном HBM? Если нет, могу ли я указать тип по умолчанию, который NH использует для перечислений (и что это)?

alt text

Ответы [ 6 ]

23 голосов
/ 23 августа 2010

Если вы используете мое соглашение enum, у вас нет такой проблемы.

public class EnumConvention : IPropertyConvention, IPropertyConventionAcceptance
{
    public void Apply(IPropertyInstance instance)
    {
        instance.CustomType(instance.Property.PropertyType);
    }

    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Property.PropertyType == typeof(AddressType)  ||
            x.Property.PropertyType == typeof(Status) ||
            x.Property.PropertyType == typeof(DayOfWeek));
    }
}

Затем вы можете отобразить вашу собственность как обычную:

Map(x => x.DayOfWeek);

РЕДАКТИРОВАТЬ: Обновлено соглашение о выборе конкретных перечислений для использования в преобразовании int.Все перечисления, которые здесь не отмечены, будут отображаться как строки.Возможно, вам придется немного поэкспериментировать с тем, что на самом деле проверить.Я не уверен, будет ли свойство type делать это напрямую.

5 голосов
/ 16 августа 2013

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

Map(x => x.DayOfWeek).CustomType<enumType>();

Это помогло мне: оно перестало обновляться каждый раз.

Источник: https://groups.google.com/forum/#!searchin/fluent-nhibernate/enum/fluent-nhibernate/bBXlDRvphDw/AFnYs9ei7O0J

4 голосов
/ 20 августа 2010

Один из обходных путей, который я использую, состоит в том, чтобы создать поле поддержки int и позволить NHibernate использовать его для отображения.

Всякий раз, когда NHibernate должен выполнить приведение, чтобы сравнить новое значение со старым - оно всегда помечается как грязное - вызывая сброс.

1 голос
/ 21 февраля 2011

Простой способ, который мне помог, состоял в том, чтобы изменить пользовательский тип отображения с int на PersistentEnumType. Обязательно объявите универсальную версию, чтобы сделать вашу жизнь проще:

public class PersistentEnumType<T> : PersistentEnumType {
    public PersistentEnumType() : base(typeof(T)) {}
}

Тогда используйте

Map(x => x.DayOfWeek)
    .CustomType<PersistentEnumType<System.DayOfWeek>>();

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

Подробнее здесь .

0 голосов
/ 23 августа 2010

Вы могли бы рассмотреть альтернативный подход; Я обнаружил, что использование хорошо известных типов экземпляров Фабио Мауло неоценимо для такого использования. Преимущество этого становится очевидным каждый раз, когда вы пытаетесь расширить возможности базового перечисления (например, предоставить локализованное описание и т. Д.)

0 голосов
/ 21 августа 2010

Это зависит от того, нужно ли вам специально указывать DayOfWeek в виде целого числа.

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

Я бы, вероятно, карту:

Карта (x => x.DayOfWeek) .CustomType ();

и создайте свойство только для чтения, которое представляет значение DayOfWeek в виде целого числа, если оно действительно требуется. В любом случае, отображение как фактический тип должно работать и предотвращать ложное загрязнение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...