在NHibernate中映射枚举集合

时间:2010-09-27 18:03:05

标签: .net nhibernate enums

我正在尝试使用Fluent NHibernate映射NHibernate中的枚举集合,然后对该枚举集合的内容执行查询,但系统每次都会抛出异常。

我有一个Widget类,映射到Widget表。还有一个WidgetType枚举,Widget的单个实例可以有许多WidgetTypes,通过WidgetTypes属性进行映射。该属性需要映射到一个单独的表WidgetTypeRef,它有两个整数列:WidgetId和WidgetType。

public class Widget
{
  /* omitted */
  public IList<WidgetType> WidgetTypes { get; set; }
}
public enum WidgetType
{
  SomeType = 0,
  SomeOtherType = 1,
  YetOneMoreType = 2
}
public partial class WidgetMapping : IAutoMappingOverride<Widget>
{
  public void Override(AutoMapping<Widget> mapping)
  {
    /* omitted */
    mapping.HasMany(w => w.WidgetTypes)
      .Table("WidgetTypeRef")
      .KeyColumn("WidgetId")
      .Element("WidgetType");
  }
}

我无法控制数据库架构;架构无法更改。模式必须存储与Widget关联的WidgetTypes的整数值,并且不能转换为与枚举的字符串版本匹配。我非常想保持枚举的强类型,并且避免为Ref表创建一个新的实体。

其他类具有基于枚举的类型属性,可以使用“.CustomType(typeof(someTypeEnum)”配置,但HasMany映射上没有CustomType属性。使用上面的HasMany映射,对集合的查询会抛出“无法确定成员类型“例外。

这甚至可能吗?该房产应该如何设置?如何配置Fluent映射?如何查询集合(我的查询只需要等同于Any或Contains)?

1 个答案:

答案 0 :(得分:2)

public class EnumToIntConvention : IUserTypeConvention
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Property.PropertyType.IsEnum);
    }

    public void Apply(IPropertyInstance target)
    {
        target.CustomType(target.Property.PropertyType);
    }
}

使用该约定,具有以下枚举:

public enum Status
{
    Inactive = 0,
    Active = 1,
    Canceled = 2
}

并像这样设置(也应该使用Fluent映射):

var cfg = Fluently.Configure()
    .Database(configurer)
    .Mappings(m =>
    {
        m.AutoMappings.Add(AutoMap.Assemblies(Assembly.GetExecutingAssembly())
            .Where(type => AutomapAssemblies.Contains(type.Namespace))
            .Conventions.Add<EnumToIntConvention>()  // Magic code goes here!
            .Conventions.Add());
    });

将保存integer值而不是string值。