Ich arbeite mit einer SQL Server-Datenbank mit über 1000 Tabellen, einigen hundert Ansichten und mehreren tausend gespeicherten Prozeduren. Wir möchten Entity Framework für unsere neueren Projekte verwenden und arbeiten an unserer Strategie dafür. Ich möchte wissen, wie ich die Tabellen am besten in verschiedene Modelle aufteilen kann (EDMX oder DbContext, wenn wir zuerst Code verwenden). Ich kann mir auf Anhieb ein paar Strategien vorstellen:
- Nach Schema
aufteilen Wir haben unsere Tabellen auf wahrscheinlich ein Dutzend Schemata aufgeteilt. Wir könnten ein Modell pro Schema erstellen. Dies ist jedoch nicht perfekt, da dbo mit über 500 Tabellen / Views immer noch sehr groß ist. Ein weiteres Problem ist, dass bestimmte Arbeitseinheiten Transaktionen ausführen müssen, die sich über mehrere Modelle erstrecken, was die Komplexität erhöht, obwohl EF dies meiner Meinung nach ziemlich einfach macht. - Nach Absicht
aufteilen Anstatt sich Gedanken über Schemata zu machen, sollten Sie die Modelle nach Absicht aufteilen. Wir haben also verschiedene Modelle für jede Anwendung, jedes Projekt, jedes Modul oder jeden Bildschirm, je nachdem, wie detailliert wir arbeiten möchten. Das Problem dabei ist, dass es bestimmte Tabellen gibt, die zwangsläufig in jedem Fall verwendet werden müssen, z. B. User oder AuditHistory. Fügen wir diese zu jedem Modell hinzu (verstößt meiner Meinung nach gegen DRY), oder befinden sich diese in einem separaten Modell, das von jedem Projekt verwendet wird? - Überhaupt nicht aufteilen - ein Riesenmodell
Aus Sicht der Entwicklung ist dies offensichtlich einfach, aber aus meiner Forschung und meiner Intuition scheint es, als könnte es eine schreckliche Leistung erbringen, sowohl zur Entwurfszeit als auch zur Kompilierungszeit und möglicherweise zur Laufzeit.
Was ist die beste Vorgehensweise für die Verwendung von EF für eine so große Datenbank? Welche Strategien werden speziell beim Entwerfen von Modellen für dieses Volumen von DB-Objekten verwendet? Gibt es Optionen, bei denen ich nicht besser darüber nachdenke als oben?
Ist dies auch ein Problem in anderen ORMs wie NHibernate? Wenn ja, haben sie bessere Lösungen als EF gefunden?
quelle
Antworten:
Persönlich habe ich versucht, ein großes Schema für alle meine Entitäten in einem ziemlich komplexen, aber kleinen Projekt (~ 300 Tabellen) zu erstellen. Wir hatten eine extrem normalisierte Datenbank (Normalisierung der 5. Form (ich sage das locker)) mit vielen "vielen zu vielen" Beziehungen und extremer Durchsetzung der referenziellen Integrität.
Wir haben auch eine "Single Instance per Request" -Strategie verwendet, von der ich auch nicht überzeugt bin, dass sie geholfen hat.
Bei einfachen, relativ flachen "explizit definierten" Auflistungen, Nachschlägen und Speichern war die Leistung im Allgemeinen akzeptabel. Aber als wir anfingen, tiefe Beziehungen zu knüpfen, schien die Leistung drastisch zu sinken. Im Vergleich zu einem gespeicherten Proc gab es in diesem Fall (natürlich) keinen Vergleich. Ich bin sicher, wir hätten die Codebasis hier und da optimieren können, um die Leistung zu verbessern. In diesem Fall mussten wir jedoch aus Zeitgründen die Leistung ohne Analyse steigern, und wir sind auf den gespeicherten Prozess zurückgefallen (haben ihn immer noch zugeordnet) durch EF (da EF stark typisierte Ergebnisse lieferte), brauchten wir das nur als Rückfall in einigen Bereichen. Als wir die gesamte Datenbank durchlaufen mussten, um eine Sammlung zu erstellen (mit .include ()), verschlechterte sich die Leistung merklich, aber vielleicht haben wir zu viel verlangt.
Aus meiner Erfahrung heraus würde ich empfehlen, einen separaten .edmx pro Intent zu erstellen. Generieren Sie nur das, was Sie verwenden, basierend auf dem Umfang dieses Bedarfs. Möglicherweise verfügen Sie über kleinere EDMX-Dateien für bestimmte Aufgaben und einige größere, bei denen Sie komplexe Beziehungen durchlaufen müssen, um Objekte zu erstellen. Ich bin mir nicht sicher, wo dieser magische Ort ist, aber ich bin mir sicher, dass es einen gibt ... lol ...
Mal ehrlich, abgesehen von ein paar Fallstricken, die wir gesehen haben (komplexes Überqueren), hat der riesige .edmx aus einer "funktionierenden" Perspektive gut funktioniert. Aber Sie müssen auf die "Korrektur" -Magie achten, die der Kontext hinter den Kulissen ausführt, wenn Sie ihn nicht explizit deaktivieren. Neben der Synchronisierung der .edmx-Datei, wenn Änderungen an der Datenbank vorgenommen wurden, war es manchmal einfacher, die gesamte Oberfläche zu bereinigen und die Entitäten neu zu erstellen. Dies dauerte ungefähr 3 Minuten, sodass es keine große Sache war.
Dies war alles mit EntityFramework 4.1. Ich wäre sehr daran interessiert, auch von Ihrer Endauswahl und Ihrer Erfahrung zu hören.
Und was deine Frage zu nHibernate angeht, das ist meiner Meinung nach eine Frage der Würmer, du wirst auf beiden Seiten des Zauns bellen ... Ich höre eine Menge Leute, die EF schlagen, um zu zerschlagen, ohne durch das zu arbeiten Herausforderungen und Verständnis der Nuancen, die EF selbst eigen sind. Obwohl ich nHibernate in der Produktion noch nie verwendet habe, erhalten Sie im Allgemeinen jedoch eine genauere Kontrolle, wenn Sie manuell und explizit Dinge wie Zuordnungen erstellen müssen Ich kann Drag & Drop, Generieren und Starten von CRUDs und Abfragen mit LINQ. Ich könnte einen Mist über die Granularität machen.
Ich hoffe das hilft.
quelle
Lassen Sie mich mit einer einfachen Erläuterung beginnen: Ich habe keine Erfahrung mit einer so großen Datenbank, sodass der Rest meiner Antwort nicht auf dem Beispiel der realen Welt basiert.
Sie haben also eine BIG-Datenbank und möchten diese mit ORM / EF verwenden. Ich würde mit der zweiten Wahl gehen. Hier ist meine einfache Erklärung, warum:
quelle
Ich würde sagen, dass Sie diese Art von Frage aus technischer Sicht nicht entscheiden können. Ich würde empfehlen, dass Sie Ihre Architektur basierend auf Ihren Anwendungsfällen (User Stories usw.) erstellen. Finden Sie zuerst Ihre Geschäftsobjekte. Ein Entitätsobjekt ist nicht standardmäßig ein Geschäftsobjekt. In der Regel haben Sie ein Geschäftsobjekt vor den Entitätsobjekten. Dann können Sie schrittweise entscheiden, was Sie wirklich benötigen, basierend auf den Benutzeranforderungen.
"Ein guter Architekt maximiert die Anzahl der nicht getroffenen Entscheidungen." Robert C. Martin
http://cleancoder.posterous.com/architecture-deference
quelle
Ich benutze einen hybriden Ansatz - OLTP-Daten werden von EF verarbeitet, während umfangreiche Vorgänge wie Batch-Einfügungen, Massenaktualisierungen, Berichtsabfragen usw. von Stored Procs verarbeitet werden. Dies erleichtert auch den Migrationspfad, wenn Sie nicht alle Daten auf einmal neu schreiben.
quelle