I have an object model that looks like this (pseudo code):
class Product {
public ISet Recommendations {get; set;}
public ISet
JoinAlias
is another way to eagerly fetch related records, plus we can use it to dig another level deeper through Recommendations
down to Images
. We'll use LeftOuterJoin
because we want to load the product even if it has no recommendations.
Product recommendationAlias = null;
Image imageAlias = null;
return CurrentSession.QueryOver()
.JoinAlias(x => x.Recommendations, () => recommendationAlias, JoinType.LeftOuterJoin)
.JoinAlias(() => recommendationAlias.Images, () => imageAlias, JoinType.LeftOuterJoin)
.Where(x => x.Id == ID)
.TransformUsing(Transformers.DistinctRootEntity)
.SingleOrDefault();
When discussing eager fetching of multiple collections with NHibernate, you often hear people mention Cartesian products, but that's not a concern here. If however, you wished to load the following graph instead...
Product -> Recommendations -> Images
-> Images
... then Product.Recommendations.Images X Product.Images would form a Cartesian product that we should avoid. We could do so like this:
Product recommendationAlias = null;
Image imageAlias = null;
var productFuture = CurrentSession.QueryOver()
.JoinAlias(x => x.Recommendations, () => recommendationAlias, JoinType.LeftOuterJoin)
.JoinAlias(() => recommendationAlias.Images, () => imageAlias, JoinType.LeftOuterJoin)
.Where(x => x.Id == ID)
.TransformUsing(Transformers.DistinctRootEntity)
.FutureValue();
var imagesFuture = CurrentSession.QueryOver()
.Fetch(x => x.Images).Eager
.Where(x => x.Id == ID)
.TransformUsing(Transformers.DistinctRootEntity)
.Future();
return productFuture.Value;