7

Given a multi level object graph being called using Future as:

var Dads = db.Session.Query<Parent>().Where(P => P.EntityKey == Id)
             .ToFuture<Parent>();
var Kids = db.Session.Query<Kid>().Where(K => K.Parent.EntityKey == Id)
             .ToFuture<Kid>();

when I call var Dad = dads.ToList() I see the batch go across the wire and show in profiler.

Problem is when enumerating the collection it is still sending one off queries to the db

Eg.

for each (Kid kid in Dad.Kids) // This seems to hit the database 
{
   Teach(kid);
}

Sends a SQL query and hits the database to get each kid. Why is the object graph not populated? or is this expected behavior?

Diego Mijelshon
  • 52,548
  • 16
  • 116
  • 154
Firegarden
  • 362
  • 2
  • 10

1 Answers1

4

That behaviour is to be expected. You are simply telling NHibernate to get two collections from the database in a batch, which it is doing as told. However, you are not telling it that they are related. NH Queries with Futures do not put entities together after executing them unless they are told to do so with a join.

If you executed the separate queries without Futures you would not expect the Parent entity to suddenly have the child collection filled. Basically, Futures allow you to run things in one roundtrip. If the queries happen to have a common root with several child collections (e.g. to avoid a cartesian product), then NH is able to "combine" several collections into one entity.

Unfortunately joins with the NH LINQ Api and the ToFuture() method seem to pose a problem in the current (NH 3.0 or 3.1) implementation. You may need to use the QueryOver Api in that case.

On a side note, I think the method name is not appropriate.

Edit: After Edit of the question the method name is now ok.

Florian Lim
  • 5,332
  • 2
  • 27
  • 28
  • 1
    You are wise. Thank you I have seen a number of people recently looking for an answer to this situation. – Firegarden Mar 28 '11 at 14:54
  • 1
    An example of the solution can be found here: http://stackoverflow.com/questions/5266180/fighting-cartesian-product-x-join-when-using-nhibernate-3-0-0 – Firegarden Mar 29 '11 at 12:03
  • the queries happen to have a common root - please explain how you set up this common root. – joncodo Jun 22 '12 at 17:53
  • @JonathanO I'm not quite sure what you are referring to. Could you please elaborate? – Florian Lim Jun 23 '12 at 18:54
  • @FlorianLim I think JonathanO was referring to "If the queries happen to have a common root with several child collections (e.g. to avoid a cartesian product), then NH is able to "combine" several collections into one entity." He was wondering how this can be set up. From the sound of it, that can't be done via the LINQ API of NHibernate. This is unfortunate. It appears to be the case in v3.3 as well (which is how I found this question.) Can anyone confirm that it's still an issue in 3.3? – kdawg Feb 22 '13 at 04:40