Repository-pattern und Rückgabetypen
Ich bin mit dem repository-pattern, wo ich eine repository-Klasse pro Datenbanktabelle. Ich Frage mich, wie Sie Jungs nähern Abfragen, die Sie nur brauchen, um wieder eine bestimmte Anzahl von Spalten
Zum Beispiel sagen, ich habe das folgende
Tabelle "Artikel" (fiktive Tabelle)
ItemId
Name
PurchaseDate
Description
Price
In meinem code, ich erstelle ein Objekt mit den Feldern oben genannten Artikel.cs (derzeit nicht mit einem orm).
Wenn ich mehrere Szenarien, in denen ich nur zurückgeben
- ItemId
- Eine Kombination von PurchaseDate und Namen
- ItemId und Preis
Welches wäre die beste Herangehensweise?
- Bekommen alle Felder aus der Tabelle Artikel und eine Rückgabe-Objekt (1 repo Abfrage)
- Erstellen Sie drei Abfragen in Repo-und Rückgabe-Objekt für jeden
- Erstellen Sie drei Abfragen in Repo-und zurück nur, was gebraucht wird?
Nun stellen Sie sich dieses Szenario mit einer Tabelle mit über 10 Felder.
Persönlich mag ich die option, aber ich bin mir nicht sicher, ob es eine bessere Weise zu gehen darüber.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich persönlich benutze einen generischen Typ-repository und und habe mein Lesen
AsQueryable()
Hier ist die Schnittstelle.
und hier ist die Umsetzung.
Nun, wenn Sie brauchen, um Abfragen an das repository, die Sie wollen, so etwas zu tun.
verzeihen Sie mir, der folgende code ist ungetestet und ich bin eigentlich mehr ein VB-Typ 🙁
hoffentlich erhalten Sie den Punkt
Für meine Zwecke, bin ich mit LINQ auf dieses Besondere Projekt, aber das kann angepasst werden, um beliebige Daten-layer, den Sie mag... das ist die Schönheit eines repository-Ebene.
Ich von hier aus "persönlich" auch über eine Service-Schicht, die sich mit den Nuancen der Datenverbindung... Dinge wie
GetPersonByID
oderGetPeopleSince(DateTime marker)
. Dies ist, wo ich Streifen aus den Informationen, die ich brauche (Z.B.: Passwörter) und speichern die restlichen Informationen, die entweder ein ViewModel oder einige andere POCO.Retrieve
ist queriable, können Sie genau das tun, was Sie brauchen... lass mich tun, ein kurzes update....FirstOrDefault()
,Single()
,ToList()
etc, die den Aufruf an die Datenbank geht tatsächlich durch.Ich Methoden hinzufügen, um meine Repositorys, wenn ich Sie brauche im Gegensatz zu generischen repositories, wo Sie eine Reihe von Methoden, egal ob Sie Sie brauchen oder nicht.
Rückkehr
IQueryable
ist eine undichte Abstraktion.Werfen Sie einen Blick auf Domain-Driven Design (das Buch) und du bekommst eine gute Vorstellung davon, wie gut gestaltet repositories Aussehen sollte.
Habe ich auch geschrieben, ein rant über generische repositories: http://blog.gauffin.org/2012/02/generic-repositories-a-silly-abstraction-layer/
IQueryable
tut genau das Gegenteil von dem, was Sie wollen, ein repository zu tun - es ist einfach das, dass infrastrukturelle Anliegen direkt zurück in Ihre Domäne Schicht.Wenn Sie denken, dass der Domain-Driven Design, die Tatsache, ein einzelnes Objekt hat verschiedene Konfiguration deutet wahrscheinlich verschiedenen Domänen. Dies macht es nicht nötig, ein separates Objekt für jede, aber es ist ein gutes Muster. Ein Weg dies zu erreichen ist eine Basis-Klasse it dem minimalistischen set von Eigenschaften. Dann erstellen Sie mehr zu "domain-specific" - Klassen, Erben von der Basis.
Als für die Daten zurückgegeben werden, gibt es eine Vielzahl von Möglichkeiten, "Verkehr copping" der Strömung. Mehrere repositories trennen Sie die domains schön, zum Beispiel. Aber diese Komplexität hinzufügt (keine gute Idee, es sei denn, absolut notwendig). Ich weiß nicht, wie ein einzelnes repository Rückkehr von verschiedenen Objekten. Es ist mehr akzeptabel, wenn Sie haben einige Eigenschaften von nullable (vielleicht).
Ich bin kein Freund von LINQ to SQL als DAL, da @KethiS vorgeschlagen hat, aber ich Arbeit in einem Enterprise-Umfeld und LINQ to SQL im Grunde saugt an der Waage. Mit LINQ ist ansonsten zu groß. Nur meine zwei Cent.
Wenn Sie zurückkehren können, ein Objekt geben, das besser ist. Wenn der Unterschied in der Objekte ist auf der Grundlage von Berechtigungen, prüfen, löschen der Daten, die der Benutzer nicht sehen sollten. Beachten Sie jedoch, ist dies nicht so skalierbar, wenn Sie greifen eine große Anzahl von Objekten.
Ich mag Linq-basierte repositories für diese Art der Sache. Linq2SQL, MSEF, oder Linq2NH, die Ihnen erlauben würden, die über das Select () - Methode, definieren Sie Ihre Spalte Liste. Sie würde dann erhalten Sie ein domain-Objekt oder Entity-Klasse aufgefüllt, mit nur das, was Sie angegeben haben. Sie können zusätzlichen code zum anzeigen dieser in ein DTO, oder verwenden Sie einfach die domain-Klasse zu wissen, dass es war nicht vollständig "hydratisiert".
Warum würden Sie wieder alle Felder, wenn Sie auch tatsächlich benötigen nur wenige von Ihnen? Wählen Sie die Felder, die Sie wirklich wollen, wenn Sie besorgt über die Leistung. Ich bin kein großer fan von streng nach einem design-Muster, vielleicht sollten Sie erwägen, ändern Sie das design entsprechend Ihrer Anforderung.