Подтвердить что ты не робот

Fluent NHibernate Map Enum в качестве таблицы поиска

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

public enum Level
{
    Bronze,
    Silver,
    Gold
}

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

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

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

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

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

4b9b3361

Ответ 1

Чтобы отобразить свойство 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() });
}

Ответ 2

Я бы этого не сделал, потому что ваше объявление 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 и VALUE. Создайте свое перечисление со своими статическими членами и сделайте приложение запрашивать базу данных для имен и значений при ее запуске. Если что-то не соответствует, делайте все, что вам нужно. Кроме того, это не гарантирует, что ваша таблица не будет меняться во время работы вашей программы, поэтому вы можете быть уверены, что этого не делает.