流暢なNHibernateで列挙型をint値としてどのようにマッピングしますか?


88

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

私は現在PersistenceModel、それが何らかの違いを生む場合、私の慣習を設定するために使用しています。前もって感謝します。

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


5
問題を自分で解決した場合は、答えてから、正しい答えとしてマークを付けて、今後の検索者が見つけられるようにします。
ジェフマーティン

答えを投稿していただけますか?
mxmissile 2009年

やったね 遅れて申し訳ありません。ライブラリの最新バージョンが必要なだけだったので、私は問題ではない質問で何をすることになっていたのか本当にわかりませんでした。
Garry Shutler、

2
Googleボットの食べ物:enumマッピングにこれを実装する前に、「コレクションの読み込みへの不正なアクセス」を取得していました。
2010

回答:


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

4
これは、流暢NHibernateの最新バージョンのための正しい答えである
ショーン・チェンバース

バンプ。^^ショーンが言ったこと。
マーティンスハネク2010年

1
これはすべての列挙型で正常に機能するように見えますが、一部を文字列として、一部を整数として必要な場合はどうでしょうか。これは、プロパティマッピングレベルで構成可能である必要があると思います。
UpTheCreek 2010年

4
以下の@SztupYによる回答を参照して、これを拡張してnull可能な列挙型を許可してください。stackoverflow.com/questions/439003/…–
Jon Adams、

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 */

3
デフォルトは「intモード」です。列挙型を文字列として永続化するのは誰ですか?
アンドリューブロック

4
文字列値が既に存在するレガシーデータベースである可能性があります
Chris Haines

4
+1ヘイニー。@ Andrew Bullock:あなたの質問への回答:現実のデータベースを扱う人。
スカイサンダーズ

FNにIPropertyインターフェイスはありますか?
Tien Do

40

null許容列挙型(など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);
    }
}

4
+1この追加のために!最初のバージョンはnull可能な列挙型では機能しません(文字列のままです)。
longda '10 / 08/11

@SztupYデータベースの列タイプはint?そして、型がフラグを受け入れるとき?例:MyEnum.Active | MyEnum.Paused
ridermansb 2013年

@RidermandeSousaBarbosaは:フラグはこちらをご確認ください:stackoverflow.com/questions/2805661/...
SztupY

25

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

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

私のために働く!


2
最も単純な回答を提供してくれてありがとう
マイク

これに関する私の唯一の欠点は、すべての列挙型に適用することを忘れないようにする必要があるということです。それが規約が作成された目的です。
Garry Shutler、2010

これは読み取りには機能しますが、条件クエリを実行すると失敗しました。私が試したすべてのケースで、コンベンションの設定(この質問への回答を参照)は機能しました。
トーマス・ブラット

まあそれは素晴らしいと思った-しかし、これは問題を引き起こすでしょう:この投稿を見てください。nhforge.org/blogs/nhibernate/archive/2008/10/20/...
UpTheCreek

@UpTheCreek固定されており、現在NHチームからジェームズ・グレゴリーによって推奨されているようです:mail-archive.com/fluent-nhibernate@googlegroups.com/...
イリヤ・コーガン

1

自動マッピングで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>();
                });
    }

*次に、CreateSessionFactoryCastle WindsorなどのIoC(PersistenceFacilityとインストーラーを使用)で簡単に使用できます。*

    Kernel.Register(
        Component.For<ISessionFactory>()
            .UsingFactoryMethod(() => CreateSessionFactory()),
            Component.For<ISession>()
            .UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession())
            .LifestylePerWebRequest() 
    );


0

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

マッピングクラス

パブリッククラスTransactionMap:ClassMap Transaction
{
    public TransactionMap()
    {
        //その他のマッピング
        .....
        //列挙型のマッピング
        Map(x => x.Status、 "Status")。CustomType();

        Table( "トランザクション");
    }
}

列挙型

パブリック列挙型TransactionStatus
{
   待機中= 1
   処理済み= 2
   RolledBack = 3
   ブロック= 4、
   払い戻し= 5
   AlreadyProcessed = 6
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.