如何使用fluent NHibernate将枚举映射为int值?

如何使用fluent NHibernate将枚举映射为int值?,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,问题说明了一切,默认情况下它映射为字符串,但我需要它映射为int 我目前正在使用PersistenceModel来设置我的约定,如果这有什么不同的话。提前谢谢 更新 发现从主干上获取最新版本的代码解决了我的难题。您可以创建一个NHibernateIUserType,并使用属性映射上的CustomTypeIs()指定它。因此,如上所述,从主干上获取最新版本的Fluent NHibernate让我到达了需要的位置。具有最新代码的枚举的映射示例如下: Map(quote => quote.Sta

问题说明了一切,默认情况下它映射为
字符串
,但我需要它映射为
int

我目前正在使用
PersistenceModel
来设置我的约定,如果这有什么不同的话。提前谢谢

更新
发现从主干上获取最新版本的代码解决了我的难题。

您可以创建一个NHibernate
IUserType
,并使用属性映射上的
CustomTypeIs()
指定它。

因此,如上所述,从主干上获取最新版本的Fluent NHibernate让我到达了需要的位置。具有最新代码的枚举的映射示例如下:

Map(quote => quote.Status).CustomTypeIs(typeof(QuoteStatus));
自定义类型强制将其作为枚举实例处理,而不是使用
genericenumapper

实际上,我正在考虑提交一个补丁,以便能够在一个持久化字符串的枚举映射器和一个持久化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 */
fluent.Configure(nHibConfig)
.Mappings(映射配置=>
{
mappingConfiguration.FluentMappings
.ConventionDiscovery.AddFromAssemblyOf();
})
./*其他配置*/

定义此约定的方式在以前有时会改变,现在是:

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);
    }
}
公共类枚举约定:IUserTypeConvention
{
公共无效接受(IAcceptanceCriteria标准)
{
Expect(x=>x.Property.PropertyType.IsEnum);
}
公共无效应用(IPropertyInstance目标)
{
target.CustomType(target.Property.PropertyType);
}
}

不要忘记可为空的枚举(如
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);
    }
}
公共类枚举约定:IUserTypeConvention
{
公共无效接受(IAcceptanceCriteria标准)
{
Expect(x=>x.Property.PropertyType.IsEnum||
(x.Property.PropertyType.IsGenericType&&
x、 Property.PropertyType.GetGenericTypeDefinition()==typeof(可为空)&&
x、 Property.PropertyType.GetGenericArguments()[0].IsEnum)
);
}
公共无效应用(IPropertyInstance目标)
{
target.CustomType(target.Property.PropertyType);
}
}

我就是这样将枚举属性映射为int值的:

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

为我工作

对于使用Fluent NHibernate和自动映射(以及可能的IoC容器)的用户:

IUserTypeConvention
如上面朱利安的回答所示:


您应该在DB表中将这些值保持为int/tinyint。要映射枚举,需要正确指定映射。请参见下面的映射和枚举示例

映射类

public class TransactionMap : ClassMap Transaction { public TransactionMap() { //Other mappings ..... //Mapping for enum Map(x => x.Status, "Status").CustomType(); Table("Transaction"); } } 公共类事务映射:类映射事务 { 公共事务映射() { //其他映射 ..... //枚举映射 映射(x=>x.Status,“Status”).CustomType(); 表(“交易”); } } 枚举

public enum TransactionStatus { Waiting = 1, Processed = 2, RolledBack = 3, Blocked = 4, Refunded = 5, AlreadyProcessed = 6, } 公共枚举事务状态 { 等待=1, 已处理=2, 回滚=3, 阻塞=4, 退款=5, AlreadyProcessed=6,

}如果你自己解决了这个问题,你应该回答它,然后把它标记为正确的答案,这样将来的搜索者会找到它。你能发布答案吗?完成了。抱歉耽搁了。我真的不确定我应该如何处理一个更为非问题的问题,因为我只需要最新版本的库。谷歌机器人的食物:在为我的枚举映射实现此操作之前,我获得了“非法访问加载集合”。默认为“int mode”。谁坚持把枚举作为字符串?!可能是一个已有字符串值的旧数据库+1 hainesy.@Andrew Bullock:回答您的问题:任何处理真实世界数据库的人。FN中是否有IProperty接口?这是最新版本的fluent NHibernate的正确答案。看起来它适用于所有枚举类型,但如果您希望一些作为字符串,一些作为整数,该怎么办?我认为这应该在属性映射级别进行配置。请参阅下面@SztupY的答案,该答案扩展了这一点,以允许使用可为空的枚举。感谢您提供了最简单的答案。我唯一感到不安的是,您必须记住将其应用于每个枚举。这就是创建约定的目的。这对读取有效,但在尝试条件查询时失败。建立一个惯例(见这个问题的答案)在我尝试过的所有情况下都是有效的。我认为这很好,但这会引起问题:请看这篇文章@UpTheCreek这似乎已经被修复,现在由NH团队的James Gregory推荐:+1用于此添加!第一个版本不适用于可空枚举(它们仍然是字符串)。@SztupY数据库中的列类型是
int
?当类型接受标志时?例如:
MyEnum.Active | MyEnum.Paused
@ridermandesousasabosa:有关标志,请检查此处:
    Kernel.Register(
        Component.For<ISessionFactory>()
            .UsingFactoryMethod(() => CreateSessionFactory()),
            Component.For<ISession>()
            .UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession())
            .LifestylePerWebRequest() 
    );
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, }