web-dev-qa-db-ja.com

流enumなNHibernateでint値としてenumをどのようにマップしますか?

質問はそれをすべて言っています、デフォルトはstringとしてマップすることですが、intとしてマップする必要があります。

私は現在、PersistenceModelを使用して、慣習を設定します。前もって感謝します。

更新トランクから最新バージョンのコードにアクセスすることで問題が解決したことがわかりました。

87
Garry Shutler

この規則を定義する方法は時々前に変更されましたが、今では:

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);
    }
}
83
Julien

そのため、前述のように、最新バージョンのFluent NHibernateをトランクから削除すると、必要な場所に到達しました。最新のコードを持つ列挙型のマッピング例は次のとおりです。

Map(quote => quote.Status).CustomTypeIs(typeof(QuoteStatus));

カスタムタイプは、GenericEnumMapper<TEnum>を使用するのではなく、enumのインスタンスとして処理することを強制します。

文字列を保持する列挙型マッパーと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 */
45
Garry Shutler

ヌル可能列挙型を忘れないでください(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);
    }
}
40
SztupY

これは、列挙型プロパティをint値にマッピングした方法です。

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

私のために働く!

25
Felipe

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() 
    );
1
lko

DBテーブルでは、値をint/tinyintのままにしておく必要があります。列挙型をマッピングするには、マッピングを正しく指定する必要があります。以下のマッピングおよび列挙サンプルを参照してください。

マッピングクラス

 public class TransactionMap:ClassMap Transaction 
 {
 public TransactionMap()
 {
 //その他のマッピング
 .... 。
 //enum
 Map(x => x.Status、 "Status")。CustomType(); 
 
 Table( "Transaction")のマッピング; 
} 
} 

列挙

 public enum TransactionStatus 
 {
 Waiting = 1、
 Processed = 2、
 RolledBack = 3、
 Blocked = 4 
払い戻し= 5、
 AlreadyProcessed = 6、
}
0
Arkadas Kilic

NHibernate IUserTypeを作成し、プロパティマップでCustomTypeIs<T>()を使用して指定できます。

0
James Gregory