你如何将一个枚举映射为一个int值与stream利的NHibernate?

问题说明了这一切,默认情况下,它映射为一个string但我需要它映射为一个int

我目前正在使用PersistenceModel设置我的约定,如果这有什么区别。 提前致谢。

更新发现从中继获取最新版本的代码解决了我的困境。

定义这个约定的方式有时候改变了,现在是:

 public class EnumConvention : IUserTypeConvention { public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) { criteria.Expect(x => x.Property.PropertyType.IsEnum); } public void Apply(IPropertyInstance target) { target.CustomType(target.Property.PropertyType); } } 

所以,如前所述,将最新版本的stream利NHibernate从主干上取下,让我到了需要的地方。 一个枚举与最新代码的映射示例是:

 Map(quote => quote.Status).CustomTypeIs(typeof(QuoteStatus)); 

自定义types强制将其作为枚举的实例进行处理,而不是使用GenericEnumMapper<TEnum>

实际上,我正在考虑提交一个补丁,以便能够在一个持久化string的枚举映射器和一个持久化int的枚举映射器之间进行切换,因为这看起来应该是您应该可以设置为约定的东西。


这突然出现在我最近的活动上,并且在新版本的Fluent NHibernate中,事情已经发生了变化,以使这更容易。

要使所有枚举映射为整数,现在可以创build如下所示的约定:

 public class EnumConvention : IUserTypeConvention { public bool Accept(IProperty target) { return target.PropertyType.IsEnum; } public void Apply(IProperty target) { target.CustomTypeIs(target.PropertyType); } public bool Accept(Type type) { return type.IsEnum; } } 

那么你的映射只能是:

 Map(quote => quote.Status); 

你把惯例添加到你的stream利NHibernate映射像这样;

 Fluently.Configure(nHibConfig) .Mappings(mappingConfiguration => { mappingConfiguration.FluentMappings .ConventionDiscovery.AddFromAssemblyOf<EnumConvention>(); }) ./* other configuration */ 

不要忘记可空的枚举(比如ExampleEnum? ExampleProperty )! 他们需要分开检查。 这是如何完成新的FNH风格configuration:

 public class EnumConvention : IUserTypeConvention { public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) { criteria.Expect(x => x.Property.PropertyType.IsEnum || (x.Property.PropertyType.IsGenericType && x.Property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) && x.Property.PropertyType.GetGenericArguments()[0].IsEnum) ); } public void Apply(IPropertyInstance target) { target.CustomType(target.Property.PropertyType); } } 

这是我已经用int值映射了一个枚举属性:

 Map(x => x.Status).CustomType(typeof(Int32)); 

为我工作!

对于使用Fluent NHibernate和Automapping(以及潜在的IoC容器)的人来说:

IUserTypeConvention是@ Julien的上面的答案: https : IUserTypeConvention

 public class EnumConvention : IUserTypeConvention { public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) { criteria.Expect(x => x.Property.PropertyType.IsEnum); } public void Apply(IPropertyInstance target) { target.CustomType(target.Property.PropertyType); } } 

Fluent NHibernate自动映射configuration可以这样configuration:

  protected virtual ISessionFactory CreateSessionFactory() { return Fluently.Configure() .Database(SetupDatabase) .Mappings(mappingConfiguration => { mappingConfiguration.AutoMappings .Add(CreateAutomappings); } ).BuildSessionFactory(); } protected virtual IPersistenceConfigurer SetupDatabase() { return MsSqlConfiguration.MsSql2008.UseOuterJoin() .ConnectionString(x => x.FromConnectionStringWithKey("AppDatabase")) // In Web.config .ShowSql(); } protected static AutoPersistenceModel CreateAutomappings() { return AutoMap.AssemblyOf<ClassInAnAssemblyToBeMapped>( new EntityAutomapConfiguration()) .Conventions.Setup(c => { // Other IUserTypeConvention classes here c.Add<EnumConvention>(); }); } 

*然后CreateSessionFactory可以很容易地用在Castle Windsor这样的IoC(使用PersistenceFacility和installer)。 *

  Kernel.Register( Component.For<ISessionFactory>() .UsingFactoryMethod(() => CreateSessionFactory()), Component.For<ISession>() .UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession()) .LifestylePerWebRequest() ); 

你可以创build一个NHibernate IUserType ,并在属性映射上使用CustomTypeIs<T>()来指定它。

您应该在数据库表中将值保存为int / tinyint。 为了映射你的枚举,你需要正确指定映射。 请看下面的映射和枚举示例,

映射类

公共类TransactionMap:ClassMap Transaction
 {
    公共TransactionMap()
     {
         //其他映射
         .....
         //映射枚举
         Map(x => x.Status,“Status”)。CustomType();

        表( “交易”);
     }
 }

枚举

公共枚举TransactionStatus
 {
   等待= 1,
   处理= 2,
    RolledBack = 3,
   被阻止= 4,
   退款= 5,
   已经处理= 6,
 }