I've got this object graph:
// 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
}
Now I'm making a query where I'm going to return a list of As and I need all their Bs, Cs, Xs and Ys. I'm also going to group them by B into a lookup.
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);
}
}
A few things to note:
- This is a report where all data needs to be returned - unbounded results is not a problem.
- I'm doing the grouping by using
ToLookupbecause usinggroup byseems to be more complicated when you need all the actual values - you'd need to query the database for the groups and then for their actual values.
My question is how to specify the fetching strategy properly. The way I've done it is the only way I found for this to run (having fetched all of the b.x and b.y values) - but it produces SQL which seems wrong:
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
As you can see it's getting the value for a.b 3 times - b1 and b3 for the fetching, and b6 for the where clause.
- I assume this has a negative impact on DB performance - am I correct?
- Is there a way to modify my
.Fetchcalls so it only fetchesa.bonce? - Is this a good approach to my problem?