For an object graph, for example:
A { IEnum<B> } B { IEnum<C>, IEnum<D>, IEnum<E>, ... } C { IEnum<X> }
How can I look forward to loading an entire graph of an object without N + 1 problems?
Here is the pseudo code for the queries that I would ultimately want to execute:
var a = Session.Get<A>(1); // Query 1 var b_Ids = foreach(b in A.B's) => Select(b.Id); // Query 2 var c = Session.CreateQuery("from C where B in (b_Ids)").Future<C>(); // Query 3 var d = Session.CreateQuery("from D where B in (b_Ids)").Future<D>(); // Query 3 var e = Session.CreateQuery("from E where B in (b_Ids)").Future<E>(); // Query 3 // Iterate through c, d, e, ... find the correct 'B' parent, add to collection manually
The problem I am facing with this approach is that when I go to add instances of "C", "D" and "E" to the corresponding collection of the parent "B", the collection is still proxied, and when .Add is called ( ), the proxy initializes itself and performs more requests; I think NHibernate is not able to see that I already have all the data in the first level cache, which is understandable.
I tried to work around this problem by doing something like this in the Add method:
void Add(IEnum<C>) { _collection = new Collection<C>(); // replace the proxied instance to prevent initialization foreach(c) => _collection.Add(c); }
This gave me the optimal request strategy that I wanted, but caught up with me later, making persistence (NHibernate keeps track of the original by-ref collection somewhere from what I can say).
So my question is: how can I load a complex graph with child children without N + 1? The only thing I encountered was joining BC, BD, BE, which is unacceptable in my situation.
We use NH 2.1.2 with FluentHN for imaging. Upgrading to NH version 3 or using hbm / stored procedures / anything that wouldn't be outside the table.
UPDATE: One of the comments refers to the connection approach, and I came across a blog that demonstrates this approach. This work is not acceptable in our situation, but it can help someone else: Expect a selection of several child collections in round 1 with NHibernate
UPDATE 2: The Jordanian answer led me to the following posts that are related to my question: Similar question and Ayende blog . At the moment, the question asked is: "How can you carry out subqueries without a round trip on every journey."
UPDATE 3: I accepted Jord's answer, although the subtitle solution is not optimal.