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)
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. –
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). –
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