У меня есть (упрощенное) следующее
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.
Кроме того, я хочу сделать это, не изменяя мою модель.
Чтобы отобразить свойство перечисления как столбец типа 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() });
}
Я бы не стал этого делать, потому что ваше объявление 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 и ЗНАЧЕНИЕ . Создайте перечисление со своими статическими членами и заставьте приложение запрашивать базу данных для имен и значений при запуске. Если что-то не совпадает, делайте все, что вам нужно. Кроме того, это не гарантирует, что ваша таблица не изменится во время работы вашей программы, поэтому вам лучше убедиться, что это не так.