Repository-Muster - wie richtig zu verarbeiten, Verknüpfungen und komplexe Abfragen?

Ich habe ein problem mit dem Repository-Muster - wie zum ausführen von JOIN-Operationen zwischen mehreren repositories. In diesem Projekt werden wir verwenden, MVC, EF, DDD. Ich bin mir bewusst, dass diese Art von Frage wurde hier mehrmals, ich Verweise auf diese Fragen später in diesem.

Zwischen generischen repository-Modell (IRepository) und der spezifischen repository-Modell, ich wählte bestimmte option, da sehe ich, ORM (in unserem Fall EF), wie eine generische repository-pattern selbst, so dass es nicht sinnvoll ist, zum hinzufügen eines weiteren generischen repository und wir würden eher passen das repository an, um die Domäne muss.

Das problem ist, dass ich noch einige (~ 10) Tabellen mit vielen Zeilen (in Millionen), und die ich ausführen Verbindet, so mit IList-oder IEnumerable ist keine praktikable option.

Mein Verständnis (und meine Sicht) ist, dass IQueryable sollte nicht aus dem repository ("Was passiert, DAL, bleiben sollte, DAL."). Es wäre viel einfacher zu entlarven IQueryable und verwenden Sie es in LINQ-in-service, aber stark gegen die Trennung von Bedenken und untergräbt die Rolle der Archive - in einem solchen Fall, wird der Dienst das gleiche tun wie repository. Wählen Sie ein paar, diese Artikel sichern diese Perspektive (oder besser überzeugung):

Zurück IQueryable<T> oder nicht zurück IQueryable<T>

Sollte ich zurück IEnumerable<T> oder IQueryable<T> aus meiner DAL?

http://www.shawnmclean.com/blog/2011/06/iqueryable-vs-ienumerable-in-the-repository-pattern/

http://blog.ploeh.dk/2012/03/26/IQueryableTisTightCoupling/

Gibt es auch ähnliche Fragen und Lösungen, z.B. Wie join Mehrere Tabellen mit Hilfe von Repository-Muster & Entity Framework?, deuten darauf hin .Include(), aber dies ist nicht eine option für schwer belastete Tabellen und joins über viele Tabellen - mit jeder BEITRETEN, verwenden wir subselects zu beschränken, was tatsächlich kam).

Diese Frage (die Antwort und Kommentare) - Wie kann ich die Abfrage cross Tabellen mit dem Repository-Pattern? - im Grunde schlägt die task-basierte Differenzierung: erstellen eines Repository für Abfragen mit JOINS, die "normalen" Paketquellen für die manipulation mit jeder Entität.

Ich sehe, wir haben diese Optionen:

  1. Auszusetzen IQueryable und Durchführung von JOIN-komplexe Abfragen in services; ich bin aufrichtig der Meinung, es ist anti-Muster, ich mag das nicht.
  2. Nicht verwenden Repository für diese ~ 10 Tabellen und Abfragen ausführen, die in-Dienste; einige Artikel vorgeschlagen, dass die Verwendung von EF ist genug (z.B. Ist es okay, zu umgehen, um den repository-pattern für komplexe Abfragen?), die ich nicht mit Zustimmen dass.
  3. Verwenden den task-basierte Differenzierung, nicht einschränken repositories 1:1 repo:Person (bin ich dafür, diese option)
  4. Etwas ganz anderes?

So, was würden Sie vorschlagen? Wieder und wieder, vielen Dank.

  • Der Punkt, der den Umgang eines Endlagers ist zu ignorieren, die db alle zusammen. Db-engines, Tabellen, sql-joins etc sind details der Implementierung der ein repository, das nie die Ausdauer-Grenze. SO ist die app nie weiß, über EF oder verbindet und niemals den Zugriff auf die db direkt. Die app erkennt nur über das repository und er erzählt was zu machen/bekommen, nicht so, um es zu tun
  • Hallo Robert, ich bin kämpfen mit dem gleichen Problem. Was ich gefunden habe, von so weit hat mich zu dem gleichen Schluss, dass Sie hatte mit den Optionen. Mit welchem Ansatz sind Sie in der end-und warum?
  • Hi, bei komplexen Abfragen, verwenden wir einige spezielle repositories nur für Abfragen, und in unserem Fall, Abfragen in diese Repositorys sind in der Regel durchgeführt, indem Sie gespeicherte Prozeduren, die Rückgabe mehrerer Datensätze (wenn join ist nicht genug) und das repository übersetzt, die in bestimmten (meist komplizierte) domain-Objekt (das ist nicht die Person per se, aber ich glaube, es ist immer noch nicht Missbrauch von DDD).
  • Und für die nicht-komplexe Abfragen? Zum Beispiel GetOrderLineByOrderId oder GetOrderLineByCustomerId
  • Für standard-Abfragen verwenden wir normale repository um aggregate root und EF6, im genannten Fall wäre das so etwas wie OrderRepository, die sich mit um-Domäne.
Schreibe einen Kommentar