Question says it all really, the default is for it to map as a string
but I need it to map as an int
.
问题说真的,默认是它映射为字符串,但我需要它作为一个int映射。
I'm currently using PersistenceModel
for setting my conventions if that makes any difference. Thanks in advance.
我目前正在使用PersistenceModel设置我的约定,如果这有任何区别。提前致谢。
Update Found that getting onto the latest version of the code from the trunk resolved my woes.
更新发现从主干上获取最新版本的代码解决了我的困境。
The way to define this convention changed sometimes ago, it's now :
定义此约定的方式有时会改变,现在是:
public class EnumConvention : IUserTypeConvention
{
public void Accept(IAcceptanceCriteria criteria)
{
criteria.Expect(x => x.Property.PropertyType.IsEnum);
}
public void Apply(IPropertyInstance target)
{
target.CustomType(target.Property.PropertyType);
}
}
So, as mentioned, getting the latest version of Fluent NHibernate off the trunk got me to where I needed to be. An example mapping for an enum with the latest code is:
因此,正如所提到的那样,将最新版本的Fluent NHibernate从主干上移开,让我到达了我需要的位置。使用最新代码的枚举的示例映射是:
Map(quote => quote.Status).CustomTypeIs(typeof(QuoteStatus));
The custom type forces it to be handled as an instance of the enum rather than using the GenericEnumMapper
.
自定义类型强制将其作为枚举的实例处理,而不是使用GenericEnumMapper
I'm actually considering submitting a patch to be able to change between a enum mapper that persists a string and one that persists an int as that seems like something you should be able to set as a convention.
我实际上正在考虑提交一个补丁,以便能够在持久化字符串的枚举映射器和持久化int的映射器之间进行更改,因为这似乎是您应该能够设置为约定的东西。
This popped up on my recent activity and things have changed in the newer versions of Fluent NHibernate to make this easier.
这突然出现在我最近的活动中,并且在较新版本的Fluent NHibernate中发生了变化,使这更容易。
To make all enums be mapped as integers you can now create a convention like so:
要将所有枚举映射为整数,您现在可以创建如下的约定:
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;
}
}
Then your mapping only has to be:
那么你的映射只需要:
Map(quote => quote.Status);
You add the convention to your Fluent NHibernate mapping like so;
你可以像这样添加Fluent NHibernate映射的约定;
Fluently.Configure(nHibConfig)
.Mappings(mappingCOnfiguration=>
{
mappingConfiguration.FluentMappings
.ConventionDiscovery.AddFromAssemblyOf();
})
./* other configuration */
Don't forget about nullable enums (like ExampleEnum? ExampleProperty
)! They need to be checked separately. This is how it's done with the new FNH style configuration:
不要忘记可以为空的枚举(如ExampleEnum?ExampleProperty)!它们需要单独检查。这就是新FNH样式配置的完成方式:
public class EnumConvention : IUserTypeConvention
{
public void Accept(IAcceptanceCriteria 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);
}
}
this is how I've mapped a enum property with an int value:
这就是我用int值映射枚举属性的方法:
Map(x => x.Status).CustomType(typeof(Int32));
works for me!
适合我!
For those using Fluent NHibernate with Automapping (and potentially an IoC container):
对于那些使用Fluent NHibernate和Automapping(以及可能是IoC容器)的人:
The IUserTypeConvention
is as @Julien's answer above: https://stackoverflow.com/a/1706462/878612
IUserTypeConvention是@ Julien的答案:https://stackoverflow.com/a/1706462/878612
public class EnumConvention : IUserTypeConvention
{
public void Accept(IAcceptanceCriteria criteria)
{
criteria.Expect(x => x.Property.PropertyType.IsEnum);
}
public void Apply(IPropertyInstance target)
{
target.CustomType(target.Property.PropertyType);
}
}
The Fluent NHibernate Automapping configuration could be configured like this:
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(
new EntityAutomapConfiguration())
.Conventions.Setup(c =>
{
// Other IUserTypeConvention classes here
c.Add();
});
}
*Then the CreateSessionFactory
can be utilized in an IoC such as Castle Windsor (using a PersistenceFacility and installer) easily. *
*然后,CreateSessionFactory可以轻松地在诸如Castle Windsor之类的IoC中使用(使用PersistenceFacility和安装程序)。 *
Kernel.Register(
Component.For()
.UsingFactoryMethod(() => CreateSessionFactory()),
Component.For()
.UsingFactoryMethod(k => k.Resolve().OpenSession())
.LifestylePerWebRequest()
);
You could create an NHibernate IUserType
, and specify it using CustomTypeIs
on the property map.
您可以创建NHibernate IUserType,并使用属性映射上的CustomTypeIs
You should keep the values as int / tinyint in your DB Table. For mapping your enum you need to specify mapping correctly. Please see below mapping and enum sample,
您应该在数据库表中将值保留为int / tinyint。要映射枚举,您需要正确指定映射。请参阅下面的映射和枚举示例,
Mapping Class
public class TransactionMap : ClassMap Transaction { public TransactionMap() { //Other mappings ..... //Mapping for enum Map(x => x.Status, "Status").CustomType(); Table("Transaction"); } }
Enum
public enum TransactionStatus { Waiting = 1, Processed = 2, RolledBack = 3, Blocked = 4, Refunded = 5, AlreadyProcessed = 6, }