你如何将一个枚举映射为一个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, }