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.
