映射到Nhibernate中的Enum位标志

时间:2009-03-23 10:13:01

标签: c# nhibernate

采用以下枚举标记

[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将按位字段映射到Flag字段?

5 个答案:

答案 0 :(得分:9)

当我映射枚举时,此枚举具有类型为'int'的后缀值,我只是将我的枚举属性映射到数据库中的int字段。我没有遇到过这个问题。
我也为标志枚举做了这个,这只是没有问题。 当您组合某些标志时,NHibernate会将这些标志的“组合”持久保存到数据库中的指定列中。
当您检索具有'flag enums'属性的实例时,NHibernate会将其重新组合回正确的组合。
例如,如果DB包含'3',那么NHibernate将使用适当值的组合填充您的属性。
事实上,我让NHibernate自己解决这个问题:

<property name="OnCallType" column="OnCallType" />

其中OnCallType列在我的DB中的类型为int,而OnCallType属性是具有flags属性的枚举类型。

答案 1 :(得分:2)

我认为最好的选择是使用Custom User Type。您可以在其中将类中的枚举映射到这两列。 以下是使用ICompositeUserMap的示例,可以将其用作指南:

虽然在你的情况下,只是实现IUserType就足够了。

答案 2 :(得分:1)

这解决了我的问题:

在类映射中,我将其添加到具有枚举类型名称的自定义类型。

Map(x => x.MyEnumProperty).CustomType<EnumType>();

答案 3 :(得分:0)

这并不能完全回答你的问题,但在类和映射中使用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;
}

我知道这不是理想的,因为它不会限制用户使用固定的枚举值,并迫使你在代码中处理原始的int,但我认为Hibernate在使用按位枚举时会遇到麻烦。它将尝试将数据库中的值映射回特定的枚举值。如果它在数据库中找到一个你没有明确枚举的值,它可能会窒息。例如。如果它在数据库中找到“3”,它将无法将其映射回枚举值,除非您明确枚举每个组合,如CanCommentAndEdit,CanCommentAndEditAndDelete等。这可能会失败使用按位枚举的目的

答案 4 :(得分:0)

我有一个用于NHibernate持久性的私有int字段和用于读取和写入int字段的标志枚举的公共Getter / Setter属性。 (NHibernate可以配置为使用私有字段)

这样你就不必诉诸伏都魔术或凌乱的常数来完成工作。