88

问题确实说明了一切,默认情况下它映射为 astring但我需要它映射为int.

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

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

4

7 回答 7

84

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

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);
    }
}
于 2009-11-10T08:48:26.267 回答
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 */
于 2009-01-14T08:44:37.063 回答
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);
    }
}
于 2010-04-26T19:27:47.147 回答
25

这就是我使用 int 值映射枚举属性的方式:

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

为我工作!

于 2010-05-14T18:39:17.973 回答
1

对于那些使用带有 Automapping 的 Fluent NHibernate(以及潜在的 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() 
    );
于 2013-12-16T11:32:18.100 回答
0

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

于 2009-01-13T15:57:52.693 回答
0

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

映射类

公共类事务映射:类映射事务
{
    公共事务映射()
    {
        //其他映射
        ......
        //映射枚举
        Map(x => x.Status, "状态").CustomType();

        表(“交易”);
    }
}

枚举

公共枚举 TransactionStatus
{
   等待 = 1,
   处理 = 2,
   回滚 = 3,
   封锁 = 4,
   退款 = 5,
   已处理 = 6,
}
于 2014-04-24T15:41:36.153 回答