2009-02-24 7 views
5

Ich habe ein ziemlich tiefes Objektdiagramm (5-6 Knoten), und wenn ich Teile davon durchquere, sagt mir NHProf, dass ich ein "Select N + 1" Problem habe (was ich machen).Verhindern Fluent NHibernate select n + 1

Die beiden Lösungen, die ich bin mir dessen bewusst sind

  1. Eager laden Kinder
  2. auseinanderzubrechen mein Objektgraph (und eifrig Last)

ich wirklich nicht, entweder tun wollen dieser (obwohl ich die Grafik kann auseinander brechen später, als ich es forsee wachsend)

Vorerst ....

Ist es möglich NHibernate (mit FluentNHibernate) zu sagen, dass, wenn ich versuche, auf Kinder zuzugreifen, sie alle auf einmal zu laden, anstatt select-n + 1-in, wenn ich über sie iteriere?

Ich bekomme auch "unbegrenzte Ergebnisse gesetzt" s, das ist wahrscheinlich das gleiche Problem (oder vielmehr, wird durch die obige Lösung wenn möglich gelöst werden).

Jede Kindersammlung (im gesamten Graphen) wird nur etwa 20 Mitglieder haben, aber 20^5 ist eine Menge, also möchte ich nicht eifrig alles laden, wenn ich die Wurzel bekomme, sondern einfach alle bekommen Kindersammlung, wenn ich in die Nähe gehe.

Edit: ein nachträglicher Einfall .... was, wenn ich Paging einführen möchte, wenn ich Kinder darstellen möchte? Muss ich hier meine Objektgrafik aufbrechen, oder gibt es ein bisschen Nachlässigkeit, die ich anwenden kann, um all diese Probleme zu lösen?

Antwort

9

Es klingt für mich, dass Sie den Ansatz der Verwendung Ihres Domänenmodells verfolgen möchten, anstatt eine spezifische Nhibernate-Abfrage für dieses Szenario zu erstellen. Angesichts dessen würde ich vorschlagen, dass Sie sich das Batch-Size-Attribut ansehen, das Sie auf Ihre Sammlungen anwenden können. Die Fluent NHibernate Fluent Interface noch nicht dieses Attribut unterstützen, sondern als eine Arbeit um können Sie:

HasMany(x => x.Children).AsSet().SetAttribute("batch-size", "20") 

der allgemeine Mangel an Informationen über die genaue gegebenes Szenario kann ich nicht sicher sagen, ob Batch-Größe ist die ideale Lösung, aber ich empfehle Ihnen sicherlich, es auszuprobieren. Wenn Sie nicht bereits haben, empfehle ich Ihnen diese lesen:

http://www.nhforge.org/wikis/howtonh/lazy-loading-eager-loading.aspx

http://nhibernate.info/doc/nhibernate-reference/performance.html

Die NHibernate Leistungsdokumentation erklären, wie Batch-Größe funktioniert.

Edit: Mir ist keine Möglichkeit bekannt, aus Ihrem Domänenmodell zu paginieren. Ich empfehle Ihnen, NH-Abfragen für Szenarien zu schreiben, in denen Paging erforderlich ist.

+0

"Es klingt für mich, dass Sie den Ansatz verfolgen möchten, Ihr Domänenmodell zu verwenden, anstatt eine spezifische Nhibernate-Abfrage für dieses Szenario zu erstellen." definitiv. das Letzte, was ich will, sind spezifische Abfragen. Ich überprüfe das Zeug, ta –

+3

hinweis -> fluent-nh-Schnittstelle unterstützt jetzt das BatchSize() - Attribut – KevinT

0

Edit: ein nachträglicher Einfall .... was ist, wenn ich Paging einzuführen wollen, wenn ich Kinder machen wollen? Muss ich mein Objekt Graph hier brechen, oder gibt es einige Sneakyness kann ich beschäftigen, um alle diese Probleme zu lösen?

Nun, wenn Sie nur die Kinder laden, dann können Sie sie pagen :). Aber wenn du etwas wie LoadParent UND PageChildren willst, dann glaube ich nicht, dass du das kannst.