Ist das schlechtes Design? Wie kann es verbessert werden?

9

Ich habe vor einiger Zeit Folgendes geschrieben, aber ich bin kürzlich gekommen, um es zu überprüfen, und denke jetzt nicht, dass es gutes Design ist.

Das Design ist für eine Art modulare Datenbankschicht unter Verwendung von Entity Framework 4 vorgesehen. Es gibt ein einzelnes Datenbankobjekt, das (träge) Entity Framework-Kontexte aus externen Bibliotheken an einem bestimmten Speicherort lädt, und Instanzen der geladenen Kontexte werden in einer Hash-Tabelle gegen gespeichert ihren Namen (EG "ContentMgmtContext").

Der gesamte Kontakt mit der Datenbank in diesem System erfolgt über gespeicherte Prozeduren. Um die Datenbank aufzurufen, sieht die Signatur der Abfragemethode folgendermaßen aus:

List<TReturn> Query<TReturn>(string Context, 
                             string Procedure, 
                             TransactionScope Scope, 
                             List<ObjectParameter> QueryParameters)

Diese Modularität gefällt mir. Dieser Ansatz weist jedoch einen wesentlichen Nachteil auf: when using the database layer, the code using it has to have a reference to the library in which the context is stored, in order to access the types returned by the stored procedures through Entity Framework.Im Modell werden die Objekte aus der Datenbankebene in neue Objekte übersetzt, die von der Ansicht und dem Controller verwendet werden.

Ich denke, das ist schlechtes Design, aber wie kann ich es verbessern? Ich habe überlegt, eine leere Schnittstelle hinzuzufügen IStoredProecedureObject, um jedem von einer gespeicherten Prozedur zurückgegebenen Datentyp einen gemeinsamen Basistyp zu geben. Dies scheint jedoch durch Entity Framework vereitelt zu werden. Jedes Mal, wenn die .edmxDatei neu kompiliert wird, wird der Code neu generiert und alle Ergänzungen entfernt. Gibt es eine Möglichkeit, dies zu verhindern?

Wie kann ich dieses Design verbessern? Was (sonst) ist daran falsch? Oder bin ich auf dem richtigen Weg?

Andy Hunt
quelle

Antworten:

6

Haftungsausschluss: Ich verwende kein Entity-Framework und bin stark gegen nahezu jedes Datenbank-Helfer-Framework voreingenommen.

Es sieht so aus, als hätten Sie einen Wrapper gemacht.

Ich unterscheide zwischen "Wrapper" und "Layer". Die Ebene ist etwas, das Sie möglicherweise zu einer eigenen DLL / Projekt / Jar / was auch immer kompilieren. Die Datenzugriffsschicht. Wrapper ist eine "Helfer" -Klasse, die Sie in dieser DLL verwenden. Mit dem Ziel, die Benutzeroberfläche zu vereinfachen oder Doppelarbeit zu vermeiden.

Das Problem bei der Vereinfachung der Schnittstelle für den Datenbankzugriff ist, dass dies normalerweise nicht einfach ist. Am Ende duplizieren Sie entweder die Schnittstelle von ADO / JDBC / etc. Oder Sie zwingen die Leute, es zu umgehen. Wrapper neigen dazu, alle möglichen unerwünschten Dinge zu tun. Sie können eine Verbindung automatisch schließen, wenn Sie sie zur Unterstützung einer Transaktion öffnen müssen. Sie lassen häufig fälschlicherweise Verbindungen offen, wenn Sie Daten streamen mussten, und verwenden eine dieser durch Müll gesammelten Sprachen. Um die volle Leistung der Bibliothek hinter Ihrem Wrapper zu erhalten, müssen Sie sie duplizieren.

Bibliotheken wie ADO / JDBC sind bereits eine großartige Schnittstelle. Sie sind einige der besten Beispiele für OOP, die richtig gemacht wurden. Ich würde es vorziehen, sie über einer Hülle zu verwenden, die ein Zauberer aus seinem Hut gezogen hat.

Die klassische Schnittstelle im JDBC / ADO-Stil ist bekannt und bekannt. Die Hülle, die Sie aus Ihrem Hut gezogen haben, ist es nicht.

Möchten Sie redundante "paramters.Add" reduzieren? Schauen Sie sich Generika an. Oder akzeptieren Sie einfach, dass Sie durch den Versuch, "paramter.Add" zu reduzieren, die ".add" auf eine andere Codeebene verschieben.

Übrigens ist das eine gute Frage. Ich würde es 10 Mal positiv bewerten, wenn ich könnte.

Bearbeiten: Natürlich würde JDBC-Code in der Datenzugriffsschicht versteckt sein.

Lord Tydus
quelle
Ich stimme im Nachhinein zu, dass dies eher ein Wrapper um EF 4 als um sich selbst ist. Die Idee dahinter war, die Wiederverwendung verschiedener Teile der Datenbankkonnektivität (z. B. eines Standarddatenmodells) zu ermöglichen und gleichzeitig einen einzigen Einstiegspunkt für mehrere Datenbanken mit jeweils der Wiederverwendbarkeitseigenschaft zu haben. Dieser Datenbank-Wrapper wird (zusammen mit anderer Geschäftslogik) in eine separate Bibliothek kompiliert. Wie würden Sie vorschlagen, dass ich mein Design ändere, um es zu verbessern?
Andy Hunt
+1 für den großartigen Inhalt trotz Ihrer EF-Verzerrung ... obwohl EF mehr als ein DB-Helfer-Framework ist. Sie haben Recht damit, dass er versucht, eine Verpackung dafür herzustellen.
SoylentGray