Отображение значка бит Enum в Nhibernate
Возьмите следующий флаг Enum
[Flags]
enum Permssions
{
CanComment = 1,
CanEdit = 2,
CanDelete = 4,
CanRemoveUsers = 8,
All = CanComment | CanEdit | CanDelete | CanRemoveUsers
}
В NHibernate я сопоставил перечисление перед использованием:
<property type="n.Permssions, n.Permssions"
name="Permssions" column="Permssions"></property>
Мой вопрос: как мне отобразить побитовое поле в поле "Флаг", используя NHibnerate?
Ответы
Ответ 1
Когда я сопоставляю перечисление, и это перечисление имеет значение поддержки типа 'int', я просто сопоставляю свое свойство enum с полем int в базе данных. Для этого у меня нет проблем.
Я сделал это и для флагов, и это просто работает без проблем.
Когда вы объединяете определенные флаги, NHibernate будет сохранять "комбинацию" этих флагов в указанном столбце базы данных.
Когда вы извлекаете экземпляр, обладающий свойством "flag enums", NHibernate вернет его обратно в правильную комбинацию.
Например, если БД содержит "3", то NHibernate заполнит ваше свойство комбинацией соответствующих значений.
Фактически, я позволил NHibernate понять все сам по себе:
<property name="OnCallType" column="OnCallType" />
где столбец OnCallType имеет тип int в моей базе данных, а свойство OnCallType - это перечисляемый тип с атрибутом flags.
Ответ 2
Я думаю, что лучшим вариантом для этого было бы использовать Пользовательский тип пользователя. В котором вы можете сопоставить Enum в своем классе с этими двумя столбцами.
Ниже приведен пример использования ICompositeUserMap, который можно использовать в качестве руководства:
Хотя в вашем случае достаточно реализовать только IUserType.
Ответ 3
Это решило проблему для меня:
В сопоставлении классов я сопоставил его с пользовательским типом с именем типа перечисления.
Map(x => x.MyEnumProperty).CustomType<EnumType>();
Ответ 4
Это точно не отвечает на ваш вопрос, но может быть проще использовать свойство Int32 в вашем классе и сопоставление и использовать статический класс констант, подобных этому, для обработки значений в коде:
public static class Permissions
{
public const int CanComment = 0x1;
public const int CanEdit = 0x2;
public const int CanDelete = 0x4;
public const int CanRemoveUsers = 0x8;
public const int All = CanComment | CanEdit | CanDelete | CanRemoveUsers;
}
Я знаю, что это не идеально, поскольку он не ограничивает ваших пользователей фиксированными значениями перечисления и заставляет вас иметь дело с сырыми ints в коде, но я думаю, что Hibernate будет иметь проблемы с побитовым перечислением. Он попытается сопоставить значение в базе данных с конкретным значением перечисления. Если он найдет значение в базе данных, которое вы явно не перечисляете, оно, вероятно, задохнется. Например. если он найдет "3" в базе данных, он не сможет отобразить его обратно до значения перечисления, если вы явно не перечисляете каждую комбинацию, такую как CanCommentAndEdit, CanCommentAndEditAndDelete и т.д. Это, вероятно, побеждает цель использования побитового перечисления.
Ответ 5
У меня было бы личное поле int для сохранения NHibernate и общедоступного свойства Getter/Setter для перечисления флага, которое читает и записывает в поле int. (NHibernate может быть настроен для работы с частными полями)
Таким образом, вам не нужно прибегать к магии вуду или беспорядочным константам, чтобы выполнить задание.