9

NHibernate 3 alpha 1を使用して、すべてのコレクションを熱心にロードしようとしています。これが ThenFetch() を使用する正しい方法かどうか疑問に思っていますか?

複数名のプロパティはコレクションです。他のものは単なる単一のオブジェクトです。

            IQueryable<T> milestoneInstances = Db.Find<T, IQueryable<T>>(db =>
            from mi in db
            where mi.RunDate == runDate
            select mi).Fetch(mi => mi.Milestone)
                .ThenFetch(m => m.PrimaryOwners)
                .Fetch(mi => mi.Milestone)
                .ThenFetch(m => m.SecondaryOwners)
                .Fetch(mi => mi.Milestone)
                .ThenFetch(m => m.Predecessors)
                .Fetch(mi => mi.Milestone)
                .ThenFetch(m => m.Function)
                .Fetch(mi => mi.Milestone)
                .ThenFetchMany(m => m.Jobs)
                .ThenFetch(j => j.Source)
                ;

NHibernate フォーラムでこれを質問することを考えましたが、残念ながら、私がいる場所からは Google グループへのアクセスが禁止されています。Fabioがここにいることは知っているので、NHibernate チームの担当者がこれについて説明してくれるでしょうか? ありがとう

4

4 に答える 4

10

どうやら、そのような場合に使用する「正しい」方法はありませんThenFetch。あなたの例は正常に動作しますが、生成された SQL には への多くの結合が含まれていますがMilestone、これは正しくありません。

IQueryOverの代わりに使用すると、 で複雑な構文IQueryable使用できます。Fetch

Fetch(p => p.B) 
Fetch(p => p.B.C) // if B is not a collection ... or 
Fetch(p => p.B[0].C) // if B is a collection ... or 
Fetch(p => p.B.First().C) // if B is an IEnumerable (using .First() extension method) 

したがって、あなたの場合は次のようになります。

query // = session.QueryOver<X>()
    .Fetch(mi => mi.Milestone).Eager
    .Fetch(mi => mi.Milestone.PrimaryOwners).Eager
    .Fetch(mi => mi.Milestone.SecondaryOwners).Eager
    .Fetch(mi => mi.Milestone.Predecessors).Eager
    .Fetch(mi => mi.Milestone.Function).Eager
    .Fetch(mi => mi.Milestone.Jobs).Eager
    .Fetch(mi => mi.Milestone.Jobs.First().Source).Eager
于 2012-08-16T12:23:58.980 に答える
3

あなたが見逃していることの1つは、 FetchMany() を使用する必要があり、 ThenFetchMany() は子プロパティがコレクションであることです。

于 2011-01-02T13:28:45.400 に答える
1
        IQueryable<T> milestoneInstances = Db.Find<T, IQueryable<T>>(db =>
        from mi in db
        where mi.RunDate == runDate
        select mi);

var fetch = milestoneInstances.Fetch(f => f.Milestone);
fetch.ThenFetch(f => f.PrimaryOwners);
fetch.ThenFetch(f => f.SecondaryOwners);
//...
于 2014-07-30T18:10:32.570 に答える
0

レオラが言ったように、あなたが使用する子供たちのコレクションをフェッチするときは必ず確認してください

FetchMany()

ThenFetchMany()

新しいフェッチはルートから取得する必要がありますが、これは常に発生するとは限りません。場合によっては、それらを個別のクエリとして作成するか、CriteriaFuturesを使用して複数のフェッチをバッチ処理する必要があります。

于 2012-08-16T17:37:12.823 に答える