Thanks, it works nice.

W dniu środa, 12 czerwca 2013 17:14:54 UTC+2 użytkownik Jacenty napisał:
>
> Hello
>
> I have to read quite complex graph of entities for large processing. From 
> one hand - I'd like to avoid lazy loading - because it leads to N+1 
> problem, from another - using fetches with ore than one collection in one 
> query leads to cartesion product in generated sql, that is unefficient, and 
> to duplicates in retrieved data (even in collections implementing 
> relationships) which breaks a domain model consistency.
> Considering the simple example Blog -> Post -> Comment, when trying to 
> query all blogs with posts and comments fetched, we can try something like 
> that:
>
> var blogs = session.Query<Blog>().FetchMany(b => b.Posts).ThenFetchMany(p 
> => p.Comments);
>
> Since it produces following SQL:
>
> select 
>     blog0_.Id as Id0_0_, ...
> from [Blog] blog0_ 
>         left outer join [Post] posts1_ on blog0_.Id=posts1_.Blog_id 
>         left outer join [Comment] comments2_ on posts1_.Id=comments2_.
> Post_id
>
> If there is more than one comment for one post, the post would be 
> duplicated in a Posts collection of its blog - my domain model becomes 
> inconsistent.
> I made a workaround by making two queries (it's similar, but not the same 
> solution, as Ayende's advice 
> here<http://ayende.com/blog/4367/eagerly-loading-entity-associations-efficiently-with-nhibernate>
> ):
>
> var blogs = session.Query<Blog>().FetchMany(b => b.Posts);
> var posts = session.Query<Post>().FetchMany(p => p.Comments);
>
> Unfortunately, NHibernate doesn't match fetches from the second query with 
> posts fetched in the first query, comments are read again for each post 
> when navigating through comments collection, and I still have the N+1 
> problem.
> Probably, after executing the second query, there are two instances of 
> each post held by one session, which is bug in my opinion.
>
> I solved it by replacing comment collections of posts fetched by first 
> query:
>
> var blogs = this.session.Query<Blog>().FetchMany(b => b.Posts);
> var posts = this.session.Query<Post>().FetchMany(p => p.Comments).
> ToDictionary(p => p.Id);
>
> foreach (var blog in blogs)
> {
>     foreach (var post in blog.Posts)
>     {
>         post.Comments = posts[post.Id].Comments;
>     }
> }
>
> But I think it's to weird code.
> Does anybody know some more elegant solution?
>
> Regards,
> Jacek Hełka
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/nhusers?hl=en-US.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to