2016-05-09 22 views
1

Ich habe eine Methode, die eine Entität aus einer Datenbank mit nHibernate abruft. Es ist ein recht komplexes Gebilde:Warum lädt nHibernate die Ergebnisse einer zukünftigen Abfrage nicht und ignoriert sie?

Level4 hat viele Level3s die viele Level2s haben, die viele Level1s ​​haben, die eine Level1Ref

So verwende ich ein paar Futures wie folgt hat:

 var future = this.Session.QueryOver<Level4>() 
      .Where(x => x.Id == level4Id) 
      .Fetch(x => x.Level3List).Eager 
      .Fetch(x => x.Level3List.First().Level2List).Eager 
      .Left.JoinAlias(x => x.Level3List,() => level3Alias, x => x.AnotherThing.Id == anotherThingId) 
      .FutureValue(); 

Und einige Abfragen wie folgt:

 this.Session.QueryOver<Level1>() 
      .Fetch(x => x).Eager 
      .Fetch(x => x.Level1Ref).Eager 
      .Fetch(x => x.Level2).Eager 
      .Inner.JoinAlias(x => x.Level2,() => level2Alias) 
      .Inner.JoinAlias(() => level2Alias.Level3,() => level3Alias, x => x.AnotherThing.Id == anotherThingId && level3Alias.Level4.Id == level4Id) 
      .Future(); 

Und dann:

Das alles erzeugt die SQL, die ich erwarten würde, aber wenn ich versuche, über Level2.Level1List zu iterieren, lädt es die Datensätze in dieser Liste.

Die Frage:

Das ist das Problem. Was habe ich? in meiner Anfrage falsch gemacht, dass nHibernate denkt, dass es in die Datenbank für Informationen gehen muss, die es bereits hat? (Ich habe eine Ahnung, die ich brauche einige meiner JoinQueryOver Bits für eifrigen Fetches zu tauschen?

(Fragen bearbeiten Beispiele zu vereinfachen)

+0

Ich denke, deine Ahnung ist richtig. 'Future' dient dazu, die Ausführung von (normalerweise) einem Batch von Abfragen zu verzögern, so dass es nur einen Umlauf in die Datenbank gibt. 'Fetch' ist wahrscheinlich das, wonach Sie suchen-- es kann assoziierte Entitäten zusammen laden. Das heißt, nach meiner Erfahrung wird es für mehr als 2 Ebenen des Holens fehlerhaft. –

+0

Nach meiner Erfahrung ist NHibernate nicht sehr eifrig zu fesseln. Ich verlasse mich normalerweise auf Lazy-Loading, das kann wirklich gut funktionieren, wenn es richtig eingerichtet ist (/ a/36070727/1178314). –

+0

Danke @ Frédéric Das Ziel für uns ist es, die Datenbank so oft wie möglich zu treffen, damit wir nicht auf Lazy-Loading setzen. – Adam

Antwort

1

Nach vielen Untersuchungen der einzige Art, wie ich diese Arbeit war die Veränderung bekommen könnte alle meine Fragen so haben sie die gleiche TRoot Dh sie ändern, so dass sie wie das alles zu starten:.. dies ist offensichtlich nicht ideal in Situationen wie dieser

this.Session.QueryOver<Level4>() 

:

Fischhändler

Sammlung von Fisch

Sammlung von Augen Sammlung von Knochen

Es bedeutet, dass ich zwei Abfragen zu schreiben und zweimal in Fisch kommt ...

Die Alternative ist zu lazy laden und Batch-Abfragen, aber die Requir Es soll nur eine Hin- und Rückfahrt in die Datenbank gemacht werden.