define subselect for a queryover
i'm certain that i'm missing something really obvious here.
what I want to acheive is quite simple-I'd like one query to load all User
s without hydrating their Posts
and Followers
collections.
using Fetch(..)
in the second query would issue left joins, which I don't want.
.Not.LazyLoad()
.Fetch.Subselect()
which would cause the second query to run the way I want it to, but then I can't turn off the .Not.LazyLoad()
for the first query (i've tried .Fetch(u => u.Posts).Lazy
but that doesn't seem to do anything).
what am I missing?
I normally set lazy=true
in my mappings (Ayende wrote about it) cause I prefer to control the behaviors in my code.
Doing so your associations will be hydrated only if you require them.
var users = session.QueryOver<User>()
.List();
Will load all your users but won't load their posts, unless you access an element of the collection:
var postTitle = users[0].Posts[0].Title;
If you want to load some users and their posts you can simply do something like this:
Post posts = null;
var users = session.QueryOver<User>()
.Where(x => x.Name == "Jamie")
.Inner.JoinAlias(t => t.Posts, () => posts)
.List();
or:
Post posts = null;
var users = session.QueryOver<User>()
.Where(x => x.Name == "Jamie")
.Inner.JoinQueryOver(t => t.Posts, () => posts)
.List();
As you might have noticed using Fetch Eager:
var users = session.QueryOver<User>()
.Where(x => x.Name == "Jamie")
.Fetch(x=>x.Posts).Eager
.List();
uses an outer join which you do not want.
The previous two examples will have a problem you've mentioned in your comment.
If you want to avoid cartesian products in your result with QueryOver you can use .TransformUsing(Transformers.DistinctRootEntity)
:
Post posts = null;
var users = session.QueryOver<User>()
.Where(x => x.Name == "Jamie")
.Inner.JoinAlias(t => t.Posts, () => posts)
.TransformUsing(Transformers.DistinctRootEntity)
.List();
You can find lot more information here.
精彩评论