6 Stimmen

Ist es möglich, eine faule IEnumerable aus einer NHibernate-Abfrage mit ICriteria zu erhalten?

Ich arbeite mit NHibernate und muss bis zu 2 Millionen Zeilen abrufen und verarbeiten. Im Idealfall könnte ich jede Zeile - eine nach der anderen - verarbeiten, ohne dass NHibernate alle 2 Millionen Zeilen auf einmal in den Speicher lädt (denn das tut weh).

Ich würde es vorziehen, eine IEnumerable zu erhalten, die den Datenleser iterativ für jedes Lesen aufrufen würde, so dass ich die gelesenen Daten verarbeiten könnte - dann verwerfen. Auf diese Weise spare ich eine Menge Speicher und kann die Ergebnisse viel schneller verarbeiten. Ich könnte die Leistung auch durch Multithreading und/oder die Verwendung von PLinq verbessern.

Ist dies mit ICriteria von NHibernate möglich? Alles, was zurückgegeben wird, scheint IList zu sein, und vollständig geladen, bevor die Auflistungsreferenz weitergegeben wird. Warum IList anstelle von IEnumerable?

Ich meine nicht "lazy" im traditionellen Sinne, den NHibernate in Bezug auf das Laden von Child- oder Parent-Objekten verwendet. Ich möchte eine lazy IEnumerable, d. h. eine Möglichkeit, eine IEnumerable aus einem ICriteria-Objekt zu erhalten . ICriteria hat nur eine List()-Methode, die die Ergebnisse in eine ArrayList lädt.

1voto

Mauricio Scheffer Punkte 97391

ICriteria hat keine Methoden, die eine IEnumerable zurückgeben, aber IQuery macht .

0voto

Strelok Punkte 47933

Sie möchten Ihren Datenzugriff in eine Methode wie die folgende verpacken:

public IEnumerable<YourObject> GetALotOfRows() {
  ..execute DataReader
  while(..read..) {
    yield return yourObject;
  }
}

Don't haben VS oder nHibernate griffbereit jetzt, so sorry für semi-Pseudo-Code. Aber der Schlüssel hier ist, "yield return" zu verwenden.

0voto

sirrocco Punkte 7891

Was für eine Art von Operation ist es, dass Sie es Zeile für Zeile machen müssen? Ich bin nur neugierig :).

Sie könnten versuchen, die Ergebnisse auszulagern - die ersten 10, die nächsten 10 ... und so weiter.

EDIT : Sie hätten also

Session.CreateCriteria(typeof(T)).SetFirstResult(0).SetMaxResults(1).UniqueResult<T>();
Session.CreateCriteria(typeof(T)).SetFirstResult(1).SetMaxResults(1).UniqueResult<T>();
Session.CreateCriteria(typeof(T)).SetFirstResult(2).SetMaxResults(1).UniqueResult<T>();

Sie erhalten das Bild, ich denke, es ist nicht der beste Weg, es ist nicht IEnumerable ... aber es würde funktionieren. Sie könnten auch SetMaxResults(10) oder etwas größeres tun, so dass nicht 1 zu einer Zeit zu senden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X