Быстрое перечисление карты NHibernate как справочная таблица

У меня есть (упрощенное) следующее

public enum Level
{
    Bronze,
    Silver,
    Gold
}

public class Member
{
    public virtual Level MembershipLevel { get; set; }
}

public class MemberMap : ClassMap<Member>
{
    Map(x => x.MembershipLevel);
}

Это составляет таблицу со столбцом под названием MembershipLevel со значением как Перечислимое строковое значение.

То, что я хочу, - чтобы все Перечисление было создано как справочная таблица с Таблицей-участником, ссылающейся на это с целочисленным значением как FK.

Кроме того, я хочу сделать это, не изменяя мою модель.

19
задан Lachlan Roche 6 April 2010 в 15:02
поделиться

2 ответа

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

public class MemberMap : ClassMap<Member>
{
    Map( x => x.MembershipLevel ).CustomType<int>();
}

Чтобы синхронизировать перечисление и таблицу поиска, я бы добавил таблицу поиска и данные в ваши сценарии sql. Интеграционный тест может проверить, что значения перечисления и справочной таблицы совпадают.

Если вы хотите, чтобы SchemaExport создавал эту таблицу, добавьте для нее класс и отображение.

public class MembershipLevel
{
    public virtual int Id { get; set; }
    public virtual string Code { get; set; }
}

public class MembershipLevelMap : ClassMap<MembershipLevel>
{
    Id( x => x.Id );
    Map( x => x.Code );
}

Если вы создаете таблицу с помощью SchemaExport, вам также необходимо будет заполнить ее:

foreach (Level l in Enum.GetValues( typeof( Level ))) {
    session.Save( new MembershipLevel{ Id = (int) l, Code = l.ToString() });
}
20
ответ дан 30 November 2019 в 04:29
поделиться

Я бы не стал этого делать, потому что ваше объявление Enum не является динамическим или проще, оно не меняется без перекомпиляции, а таблица поиска может измениться на в любой момент. Если значения Enum и таблицы поиска не совпадают, что дальше?

Другая причина в том, что если вы измените Enum (в коде), вам придется синхронизировать его с таблицей базы данных. Поскольку Enums не имеет инкрементного ключа (PK), их нельзя так просто синхронизировать. Допустим, вы удалили один член Enum из своего кода и перекомпилировали его, что должно произойти? А если вы измените значение?

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

public class MemberMap : ClassMap<Member>
{
    Map(x => x.MembershipLevel, "level")
        .CustomType<GenericEnumMapper<Level>>()
        .Not.Nullable();
}

Чтобы сохранить значения, сделайте так, как @Lachlan написал в своем ответе.

Или, если вам действительно нужна таблица поиска и вы хотите использовать Enum со строгой проверкой, создайте нормальную модель с PK (или используйте для этого значение), KEY и ЗНАЧЕНИЕ . Создайте перечисление со своими статическими членами и заставьте приложение запрашивать базу данных для имен и значений при запуске. Если что-то не совпадает, делайте все, что вам нужно. Кроме того, это не гарантирует, что ваша таблица не изменится во время работы вашей программы, поэтому вам лучше убедиться, что это не так.

5
ответ дан 30 November 2019 в 04:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: