2009-05-29 5 views
0

Ich führe ein In-House-ORM in C# geschrieben, und es hat derzeit keine Eager-Loading-Mechanismus. Um die Leistung zu verbessern, haben wir entschieden, dass das Laden dringend erforderlich ist. Daher müssen wir unseren eigenen Code schreiben, um dies zu unterstützen. (Meine Kollegen und ich haben keine Erfahrung mit irgendwelchen ORM-Tools, und außerdem dürfen wir aus alten Gründen keine populären Tools wie LinqtoSQL, Entity Framework oder Nhibernate verwenden.)Brauchen Sie Ratschläge über das Schreiben meines eifrigen Ladealgorithmus

Meine Frage ist, Welches ist die akzeptierte Best Practice zum Generieren von SQL-Anweisungen zum Eager-Laden? Ich habe darüber nachgedacht und kommen mit zwei Möglichkeiten -

ein klassisches Beispiel von 4 Tabellen Unter der Annahme - A CustomerCategory hat viele Kunden Ein Kunde hat viele Bestellen Ein Auftrag hat viele Orderdetail

und dass ich unter der Annahme, möchte Daten aus allen 4 Tabellen eifrig laden, und meine Bedingung ist - wo Order.OrderDate zwischen '2008-05-05' und '2008-12-31'

Methode 1 - Ich erzeuge ONE sql, um das zu holen Daten aus allen 4 Tabellen, die alle innere Joins verwenden, so dass ich für jede eindeutige Kombination der Primärschlüssel jeder Tabelle eine Zeile erhalte. Ich werde meine Where-Bedingung auf diesen Sql anwenden.

Methode 2 - Ich erzeuge ein SQL, um zuerst nur die Bestelldaten zu erhalten, und setze meine Where-Bedingung auf diese SQL, da das Order.OrderDate aus der Order-Tabelle kommt. Dann, basierend auf meinen Ergebnissen aus dieser Abfrage, werde ich alle Bestell-ID-Werte kennen, die ich brauche, also werde ich diese verwenden, um die Bestellungsdetaildaten abzurufen. Ich werde auch alle eindeutigen Kunden-ID-Werte kennen, die ich brauche, also werde ich diese auch verwenden, um Daten aus der Kundentabelle abzurufen, und schließlich werde ich dasselbe für die CustomerCategory tun. Diese Methode benötigt insgesamt 4 SQL-Anweisungen.

Ich kann sehen, dass die erste Methode effizienter ist, aber einer meiner Kollegen wies darauf hin, dass die zweite Methode, obwohl es 4 SQL-Anweisungen verwendet, einfacher zu schreiben und zu pflegen ist, dem stimme ich zu.

Alle Gedanken dazu würden sehr geschätzt werden. Vielen Dank!

Antwort

0

Zunächst ist Ihr Domain-Modell massiv falsch. Ich persönlich kann keine Sammlung von Customer Objekten in einer CustomerCategory rechtfertigen, weil es aus Performance-Sicht einfach keinen Sinn ergibt: Meistens braucht man einen einzelnen Kunden (plus seine Gruppe), wohingegen eine Gruppe voller Kunden einmal in einem benötigt wird blauer Mond, aber es wird die ganze Zeit da sein und alle möglichen Probleme verursachen. Gleiches gilt für Customer mit vielen Order s.

Nun zu Ihrer Frage. Es wird allgemein angenommen, dass die Anzahl der Roundtrips in der Datenbank minimiert werden sollte, selbst auf Kosten des Abrufens von mehr Daten als nötig. Das heißt, zwei große Tabellen (lang & breit) zu verbinden, um Daten aus zwei verknüpften Tabellen gleichzeitig auszuwählen, könnte ein Performance-Killer sein, also Vorsicht.

Ich empfehle Ihnen, wie es in NHibernate getan wird. Sie können die Abrufstrategie (Join, Select) für jede Zuordnung angeben, sei es eine Eins-zu-Eins-Verknüpfung oder eine Eins-zu-Eins-Verknüpfung.

Wenn Sie Microsoft SQL Server 2005 oder höher verwenden, können Sie MARS verwenden, um mehrere select s in einen Stapel zu stopfen und dann einen ganzen Graphen von Objekten zu hydratisieren, die nur einen SQL-Befehl ausgeben.

+0

danke für Ihre Hilfe. Ich gebe zu, mit unserem Modell stimmt etwas nicht. Wir werden es untersuchen, und wird nhibernate nach Ihrem Vorschlag betrachten. – janem

Verwandte Themen