映射到Nhibernate中的Enum位标志

采取以下枚举标志

[Flags] enum Permssions { CanComment = 1, CanEdit = 2, CanDelete = 4, CanRemoveUsers = 8, All = CanComment | CanEdit | CanDelete | CanRemoveUsers } 

在NHibernate中,我在使用之前映射到枚举:

  

我的问题是,如何使用NHibnerate将按位字段映射到Flag字段?

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

  

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

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

  • Money对象和NHibernate ICompositeUserType

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

这解决了我的问题:

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

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

这并不能完全回答你的问题,但在类和映射中使用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等。这可能会失败使用按位的目的枚举。

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

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