Macht eine Datenbankabstraktionsschicht wie das Entity Framework von Microsoft architektonisch die Notwendigkeit einer separaten Datenzugriffsschicht überflüssig?

11

So wie es war

Seit Jahren organisiere ich meine Softwarelösungen als solche:

  • Data Access Layer (DAL), um das Geschäft mit dem Zugriff auf Daten zu abstrahieren
  • Business Logic Layer (BLL) zum Anwenden von Geschäftsregeln auf Datensätze, zum Behandeln der Authentifizierung usw.
  • Dienstprogramme (Util), die nur eine Bibliothek gängiger Dienstprogrammmethoden sind, die ich im Laufe der Zeit erstellt habe.
  • Präsentationsschicht, die natürlich Web, Desktop, Mobile oder was auch immer sein kann.

So wie es jetzt ist

In den letzten vier Jahren habe ich das Entity Framework von Microsoft verwendet (ich bin überwiegend ein .NET-Entwickler), und ich stelle fest, dass das DAL aufgrund der Tatsache, dass das Entity Framework das bereits durchgeführt hat, umständlicher als sauber wird Aufgabe, die mein DAL früher erledigt hat: Es abstrahiert das Geschäft, CRUDs für eine Datenbank auszuführen.

Daher habe ich normalerweise eine DAL mit einer Sammlung von Methoden wie dieser:

public static IQueryable<SomeObject> GetObjects(){
    var db = new myDatabaseContext();
    return db.SomeObjectTable;
}

In der BLL wird diese Methode dann als solche verwendet:

public static List<SomeObject> GetMyObjects(int myId){
    return DAL.GetObjects.Where(ob => op.accountId == myId).ToList();
}

Dies ist natürlich ein einfaches Beispiel, da bei der BLL normalerweise mehrere weitere Logikzeilen angewendet werden, aber es scheint nur ein wenig übertrieben, eine DAL für einen so begrenzten Bereich beizubehalten.

Wäre es nicht besser, einfach die DAL aufzugeben und einfach meine BLL-Methoden als solche zu schreiben:

public static List<SomeObject> GetMyObjects(int myId){
    var db = new myDatabaseContext();
    return db.SomeObjectTable.Where(ob => op.accountId == myId).ToList();
}

Ich denke aus den oben genannten Gründen darüber nach, die DAL aus zukünftigen Projekten zu streichen, aber vorher wollte ich die Community hier nach Ihrer Rückschau / Voraussicht / Meinung befragen, bevor ich mich auf ein Projekt einlasse und ein Problem entdecke, das ich nicht habe. ' nicht vorwegnehmen.

Alle Gedanken werden geschätzt.

Aktualisieren

Der Konsens scheint zu sein, dass ein separater DAL nicht erforderlich ist, aber (hier meine eigene Schlussfolgerung zu ziehen) eine gute Idee ist, um eine Lieferantenbindung zu vermeiden. Wenn ich beispielsweise einen DAL habe, der EF-Aufrufe wie oben dargestellt abstrahiert, wenn ich Wechseln Sie jemals zu einem anderen Anbieter. Ich muss meine BLL nicht neu schreiben. Nur die grundlegenden Abfragen in der DAL müssten neu geschrieben werden. Trotzdem fällt es mir schwer, mir ein Szenario vorzustellen, in dem dies passieren würde. Ich kann bereits ein EF-Modell einer Oracle-Datenbank erstellen. MSSQL ist eine Selbstverständlichkeit. Ich bin mir ziemlich sicher, dass auch MySQL möglich ist (??), daher bin ich mir nicht sicher, ob der zusätzliche Code jemals einen lohnenden ROI erzielen würde.

Matt Cashatt
quelle
3
Wie unterscheidet sich eine / Ihre Datenzugriffsschicht von EF? Ist EF nicht eine Datenzugriffsschicht? Der einzige Grund, warum ich sehen kann, dass Ihre eigene Abstraktion zwischen Ihrer Geschäftslogik und EF erhalten bleibt, besteht darin, das Stubbing zum Testen zu vereinfachen und eine Lieferantenbindung zu vermeiden.
Marjan Venema
2
Das ist mein Punkt - es gibt keinen Unterschied in meiner Ansicht, aber ich suche nach Gegenpunkten. Vielen Dank.
Matt Cashatt
3
Persönlich sehe ich keinen Grund, eine separate DAL zu erstellen, da EF / NHibernate Datenzugriffsschichten für sich sind. Wie Marjan bereits erwähnt hat, können Sie bei EF in Betracht ziehen, wenn sich der Datenbankanbieter ändert. In NHibernate können Sie Treiber in einer Codezeile austauschen (sogar SQLite-Treiber für In-Memory-Tests), sodass es sich um (IMO) unnötigen Code handelt.
Patryk Ćwiek
3
Keine zwei DALs erforderlich. Behalten Sie, wie andere angegeben haben, Ihre BLL bei, aber achten Sie darauf, dass Sie Ihre BLL nicht an herstellerspezifische Konstrukte binden. Ich mag es immer, wenn die Dinge auf die Zeichenfolgen- oder Ganzzahlenebene herunterkommen. Dann weiß ich, dass ich leicht den gesamten BLL / DAL-Übergang über einen sehr primitiven Kanal wie Webdienste, serielle Schnittstelle, Telegraphenverbindung und nur einen Scherz freigeben kann.
Andyz Smith
1
re Update: Diese zusätzliche Ebene kann Unittests des Busineslayers viel einfacher machen, da das Verspotten / Stubben / Fälschen GetMyObjects(int myId)einfacher ist als das Verspotten / Stubben / Fälschen GetObjects.Where(ob => op.accountId == myId).ToList().
k3b

Antworten:

6

Ich bin mir nicht sicher, ob dies die Antwort ist, nach der Sie suchen.

Wir tun es, um die Dinge getrennt / organisiert zu halten. Ja, EF / NHibernate sind Datenzugriffe. Wir beschränken die Verwendung jedoch auf eine eigene Assembly mit einem generischen Repository-Setup. Diese Assembly enthält auch alle unsere NHibernate-Zuordnungen, Sitzungsfactory, Code für die Verarbeitung mehrerer Datenbanken usw.

Wir bezeichnen es immer noch als "Datenzugriffsschicht", da die gesamte Baugruppe zur Unterstützung unseres ORM vorhanden ist.

Ich sollte wahrscheinlich beachten, dass unsere Haupt-App auf 5 Datenbanken verweist, ungefähr 4-500 Domänenobjekte / Zuordnungen und verschiedene Schemata hat. Dieses Setup ist für uns also sinnvoll. Vielleicht würden Sie für eine kleinere App diese Assembly überspringen, aber .. Ich bin ein Trottel für organisierten Code und würde es wahrscheinlich trotzdem tun :)

Simon Whitehead
quelle
2

Ich betrachte EF und DAL als separate Komponenten in einem Enterprise-System. Die Datenzugriffsschicht ist eine Abstraktion, die andere Dienste verwenden, um die Datenpersistenz und -verwaltung durchzuführen. In der Regel erstellen Entity Frameworks eine nette API zum Abfragen, Aktualisieren, Löschen und Einfügen. Im Kern benötigen sie jedoch weiterhin eine direkte Verbindung zur Back-End-Datenquelle. Daher verhindert jede Art von Routing oder Firewalls, dass der EF funktioniert, sodass Sie eine EF-Vermittlungskomponente erstellen müssen.

Hier ist ein Beispiel auf hoher Ebene, das zeigt, wo DAL und EF zusammenpassen:

-------------    -------                                    ----------------    ------
| Service A | -> | DAL | -> { LOCAL / LAN / WAN ACCESS } -> | DAL BACK-END | -> | EF |
-------------    -------                                    ----------------    ------

Ich habe die Erfahrung gemacht, dass ein besseres Design darin besteht, der Geschäftslogik oder den Service-Implementierungen niemals direkten Zugriff auf die EF-Schicht zu gewähren. Stellen Sie stattdessen eine Abstraktion für die Arbeit mit allen persistenten Daten bereit, mit der Sie Anforderungen über das Netzwerk versenden oder lokal ausführen können.

Dieses Design führt jedoch einige undichte Abstraktionen ein. Es sollte also von Fall zu Fall geprüft werden.

Einige Fragen zu stellen:

  • Können alle Komponenten, die auf Ihre Daten zugreifen, eine Verbindung zum Back-End-Datenspeicher herstellen?
  • Können Sie mit Ihrem EF Datensätze über verschiedene Arten von Datenspeichern hinweg aggregieren? Zum Beispiel die Verwendung einer SQL-Datenbank mit MongoDB für Dokumente.
Andrew T Finnell
quelle
1

Heutzutage ist die Frage, ob Sie den Datenspeicher ändern wollen oder nicht, interessanter als früher, da die Frage möglicherweise nicht nur lautet, ob Sie zwischen MS SQL oder Oracle SQL wechseln würden oder nicht, sondern die größere Frage, ob Sie Möglicherweise wird eines der verschiedenen NoSQL-Datenspeicherangebote als Datenrepository verwendet.

Wenn es eine ernsthafte Möglichkeit für diese Art von Änderung gibt, kann es hilfreich sein, Ihren EF-Code in Ihrem DAL isoliert zu halten, damit Sie in Zukunft einen neuen DAL einführen können, der Ihre Repository-Anforderungen einer NoSQL-Datenbank zuordnet. Es könnte sein, dass eine solche Änderung ohnehin zu einer umfassenden Umschreibung Ihrer BLL führen würde, da sich db-bezogene Annahmen natürlich einschleichen.

In ähnlicher Weise würde EF innerhalb eines DAL wahrscheinlich das Verspotten des Datenzugriffs für Ihre BLL-Code-Unit-Tests einfacher machen.

Meiner Ansicht nach macht EF (oder ein anderes ORMS) die Notwendigkeit einer Datenzugriffsschicht nicht unbedingt ungültig.

Alex White
quelle