在NHibernate中将映射到枚举位标志

15

考虑以下枚举 Flag

[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>

我的问题是,如何使用NHibernate将一个按位字段映射到标志字段?

5个回答

9
当我映射一个枚举时,如果这个枚举有一个类型为'int'的后备值,我只需将我的枚举属性映射到数据库中的一个int字段。我没有遇到这方面的问题。
对于标志枚举,我也这样做了,而且这样做没有问题。 当您组合某些标志时,NHibernate将把这些标志的“组合”持久化到数据库中指定的列中。
当您检索具有“标志枚举”属性的实例时,NHibernate将把它恢复回正确的组合。
例如,如果DB包含“3”,那么NHibernate将使用适当的值组合填充您的属性。
事实上,我让NHibernate自己解决所有问题:
<property name="OnCallType" column="OnCallType" />

在我的数据库中,OnCallType列的类型为int,而OnCallType属性是一个带有标志属性的枚举类型。


NHibernate的幽灵对象(Ghosting)怎么样? - giammin

2

不需要自定义用户类型 - NHibernate 知道如何处理枚举标志。请查看顶部答案。 - Răzvan Flavius Panda

1
这对我解决了问题:
在类映射中,我将其映射到具有枚举类型名称的自定义类型。
Map(x => x.MyEnumProperty).CustomType<EnumType>();

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;
}

我知道这不是理想的做法,因为它不限制用户使用固定的枚举值,并强制你在代码中处理原始整数,但我认为 Hibernate 在位枚举方面可能会遇到麻烦。它将尝试将数据库中的值映射回特定的枚举值。如果它在数据库中找到一个您没有明确枚举的值,它可能会出现问题。例如,如果它在数据库中找到一个“3”,除非您明确枚举每个组合,如 CanCommentAndEdit、CanCommentAndEditAndDelete 等,否则它将无法将其映射回枚举值。这可能会破坏使用位枚举的目的。


0

我会为NHibernate持久化设置一个私有的int字段,并为标志枚举设置一个公共的Getter/Setter属性,以读写int字段。(NHibernate可以配置为使用私有字段)

这样你就不必诉诸于巫术或混乱的常量来完成工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接