问题确实说明了,默认是将其映射为string
,但我需要将其映射为int
。
我目前正在使用PersistenceModel
来设置我的约定,如果这有任何区别的话。提前谢谢。
更新 发现从主干上获取最新版本的代码解决了我的困境。
答案 0 :(得分:83)
定义此约定的方法有时会改变,现在是:
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);
}
}
答案 1 :(得分:45)
所以,如上所述,从主干上获取最新版本的Fluent NHibernate让我到达了我需要的位置。使用最新代码的枚举的示例映射是:
Map(quote => quote.Status).CustomTypeIs(typeof(QuoteStatus));
自定义类型强制将其作为枚举的实例处理,而不是使用GenericEnumMapper<TEnum>
。
我实际上正在考虑提交一个补丁,以便能够在持久化字符串的枚举映射器和持久化int的映射器之间进行更改,因为这似乎是您应该能够设置为约定的东西。
这突然出现在我最近的活动中,并且在较新版本的Fluent NHibernate中发生了一些变化,以使这更容易。
要将所有枚举映射为整数,您现在可以创建如下的约定:
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);
您可以将约定添加到Fluent NHibernate映射中,如此;
Fluently.Configure(nHibConfig)
.Mappings(mappingConfiguration =>
{
mappingConfiguration.FluentMappings
.ConventionDiscovery.AddFromAssemblyOf<EnumConvention>();
})
./* other configuration */
答案 2 :(得分:40)
不要忘记可以为空的枚举(如ExampleEnum? ExampleProperty
)!它们需要单独检查。这就是使用新的FNH样式配置的方法:
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);
}
}
答案 3 :(得分:25)
这就是我使用int值映射枚举属性的方法:
Map(x => x.Status).CustomType(typeof(Int32));
适合我!
答案 4 :(得分:1)
对于那些使用Fluent NHibernate和Automapping(以及可能是IoC容器)的人:
IUserTypeConvention
与@ Julien 的答案相同:https://stackoverflow.com/a/1706462/878612
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 Automapping配置可以像这样配置:
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和安装程序)。 *
Kernel.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod(() => CreateSessionFactory()),
Component.For<ISession>()
.UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession())
.LifestylePerWebRequest()
);
答案 5 :(得分:0)
您可以创建一个NHibernate IUserType
,并在属性地图上使用CustomTypeIs<T>()
指定它。
答案 6 :(得分:0)
您应该在数据库表中将值保留为int / tinyint。要映射枚举,您需要正确指定映射。请参阅下面的映射和枚举样本,
映射类
public class TransactionMap : ClassMap Transaction { public TransactionMap() { //Other mappings ..... //Mapping for enum Map(x => x.Status, "Status").CustomType(); Table("Transaction"); } }
<强>枚举强>
public enum TransactionStatus { Waiting = 1, Processed = 2, RolledBack = 3, Blocked = 4, Refunded = 5, AlreadyProcessed = 6, }