Текущее перечисление карты NHibernate в виде таблицы поиска - PullRequest
19 голосов
/ 03 апреля 2010

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

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 со значением в качестве строкового значения Enum.

Я хочу, чтобы весь Enum создавался как справочная таблица, причем таблица Member ссылается на него с целочисленным значением как FK.

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

Ответы [ 2 ]

20 голосов
/ 06 апреля 2010

Чтобы отобразить свойство enum как столбец 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() });
}
5 голосов
/ 09 апреля 2010

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

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

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

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

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

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

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