私はこのオブジェクトグラフを持っています:
// Lots of stuff omitted for brevity; these are all virtual properties and there
// are other properties which aren't shown on all classes.
class A {
B b;
C c;
DateTime timestamp;
}
class B {
X x;
Y y;
}
class X {
int id;
}
class C { }
class Y { }
or to put it more simply,
a = {
b: {
x { id: int },
y: { }
},
c: { },
timestamp: DateTime
}
今、私は s のリストを返すクエリを作成しており、A
すべてのB
s、C
s、X
s、およびY
s が必要です。また、それらを B でグループ化してルックアップします。
ILookup<B, A> GetData(List<int> ids) {
using (ISession session = OpenSession()) {
var query = from a in session.Query<A>()
where ids.Contains(a.b.x.id)
orderby A.timestamp descending
select a;
query = query
.Fetch(a => a.b)
.ThenFetch(b => b.x)
.Fetch(a => a.b)
.ThenFetch(b => b.y)
.Fetch(a => a.c);
return query.ToLookup(a => a.b);
}
}
注意すべき点がいくつかあります。
- これは、すべてのデータを返す必要があるレポートです。無制限の結果は問題ではありません。
- すべての実際の値が必要な場合、使用はより複雑に見える
ToLookup
ため、使用してグループ化を行っています。グループについてデータベースにクエリを実行し、次にそれらの実際の値についてクエリを実行する必要があります。group by
私の質問は、フェッチ戦略を適切に指定する方法です。私が行った方法は、これを実行するために見つけた唯一の方法です(すべてのbxとby値をフェッチしました)-しかし、間違っているように見えるSQLを生成します:
select /* snipped - every mapped field from a0, b1, x2, b3, y4, c5 - but not b6 */
from [A] a0
left outer join [B] b1
on a0.B_id = b1.BId
left outer join [X] x2
on b1.X_id = x2.XId
left outer join [B] b3
on a0.B_id = b3.BId
left outer join [Y] y4
on b3.Y_id = y4.YId
left outer join [C] c5
on a0.C_id = c5.CId,
[B] b6
where a0.B_id = b6.BId
and (b6.X_id in (1, 2, 3, 4, 5))
order by a0.timestamp desc
ご覧のとおり、値をa.b
3 回取得b1
しています。b3
フェッチとb6
where 句です。
- これは DB のパフォーマンスに悪影響を与えると思いますが、正しいでしょうか?
.Fetch
一度だけ取得するように呼び出しを変更する方法はありa.b
ますか?- これは私の問題に対する良いアプローチですか?