1

1対多の関係を持つ3つのクラスがあります

A has many B has many C

次の 2 つの条件のいずれかに該当するすべてのデータをロードしたいと考えています。

B.someField is in a list of strings

C.someOtherField is in that same list of strings

B が一致する場合もあれば、C が一致する場合もあります。すべての試合をロードし、それらをフル レベルでロードする必要があります。

つまり、B.someField が一致する場合、その B とその親 A、およびすべての子 C を読み込みます。

同様に、C.someOtherField が一致する場合、その親 B と B の親 A を読み込みます。

このクエリを作成する効率的な方法はありますか? nHibernate でどのようにしますか?

4

1 に答える 1

0

NHibernateを使用して複数の子コレクションを検索する場合、ラムダよりもLINQクエリ構文を使用する傾向があります。これは、記述がはるかに簡単であるだけでなく、コードがよりクリーンに見えるためです。

あなたを正しい方向に向けるべきこの例を見てください:

var listOfString = new List<string>() { "String1", "String2" };

var customers =
(
    from a in session.Query<A>()
    from b in a.B
    from c in b.C
    where a.Status == "Active"
            && listOfStrings.Contains( b.SomeField )
            && listOfStrings.Contains( c.someOtherField )
    select a )
    .ToList();

LINQクエリ構文を使用すると、複数のFROMを簡単に追加して、子コレクションにアクセスできます。次に、WHERE条件を適用するだけです。特定のケースでは、SQLのIN演算子と同等のLINQのContains()メソッドを使用するだけです。

また、すべての子コレクションをメモリにロードしたいようですので、NHibernateの.Fetch()メソッドを使用して、次のようにそのデータを熱心にロードしてください。

var customers =
(
    from a in session.Query<A>()
    from b in a.B
    from c in b.C
    where a.Status == "Active"
            && listOfStrings.Contains( b.SomeField )
            && listOfStrings.Contains( c.someOtherField )
    select a )
    .Fetch( x => x.B )
    .ThenFetchMany( x => x.First().C )
    .ToList();

参考までに、上記の.ThenFetchMany()メソッド内で.First()を使用することは、NHibernateのJira Issue Tracker Webサイト(https://nhibernate.jira.com/browse/NH-2972?focusedCommentId=22150&page=com )から学んだトリックです。 .atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-22150

于 2012-09-07T19:17:48.683 に答える