Ich habe mit dem ersten Einsatz von Entity Framework Code First begonnen und bin beeindruckt von der Art und Weise, wie unsere Greenfield-Anwendung rund um die Domäne und nicht um die relationalen Datenbanktabellen herum aufgebaut wird (so habe ich jahrelang gearbeitet).
Wir erstellen also Entitäten in C #, die bei jeder neuen Migration in der Datenbank reflektiert werden.
Meine Frage lautet: Sollen diese gleichen Entitäten (d. h. mit Entity Framework entworfen) die gleiche Rolle spielen wie Entitäten im Domain Driven Design (d. h. den Kern der Domain darstellen)?
Object-Relational Mapping und Domain-Driven Design sind zwei orthogonale Probleme.
ORM
Ein ORM dient nur dazu, die Lücke zwischen dem relationalen Datenmodell in Ihrer Datenbank und einem Objektmodell, jedem Objektmodell , zu überbrücken.
Eine Entität im Sinne von EF bedeutet konkret jedes Objekt , dem Sie einen Unterabschnitt Ihres relationalen Modells (und von) zuordnen möchten. Es stellt sich heraus, dass die EF-Erschaffer ihnen eine geschäftliche Konnotation geben wollten, indem sie sie Entitäten nannten, aber am Ende zwingt dich nichts dazu. Sie können View Models für alles, was es interessiert, zuordnen.
DDD
Aus DDD-Sicht gibt es keine "Entität, die mit EF entworfen wurde". Eine DDD-Entität sollte beharrlich ignorant sein und keine Spur von ORM haben. Der Domänen-Layer hat kein Interesse daran, wie, wo, ob oder wann seine Objekte gespeichert werden.
Wo die beiden sich treffen
Der einzige Punkt, an dem sich die beiden orthogonalen Konzepte schneiden, ist, wenn das Objektmodell, auf das Ihr ORM-Mapping abzielt, genau Ihr Domänenmodell ist. Dies ist mit EF möglich, das "Code first" aufruft (aber eigentlich ORM genannt werden sollte), indem es in separaten EF-Mapping-Dateien, die in einer Nicht-Domänenebene leben, auf Ihre DDD-Entitäten zeigt und keine EF-Artefakte wie Datenanmerkungen verwendet direkt in Ihren Entity-Klassen. Dies ist nicht möglich, wenn Datenbank zuerst verwendet wird, da der DDD-Reinheitsabschnitt des Geschäfts nicht erfüllt wird.
Kurz gesagt, die Begriffe kollidieren, aber sie sollten wirklich konzeptionell als zwei verschiedene Dinge betrachtet werden. Einer ist das Domain-Objekt selbst und der andere ist ein Zeiger, der den gleichen Code-Haufen anzeigen kann, aber er kann auf so ziemlich alles andere zeigen.
Sie sollten nicht gleich sein wie für andere Zwecke. Eine ORM-Entität ist eine Fassade für 1 oder mehr Tabellen, deren Zweck es ist, OOP über relationalen Tabellen zu simulieren. Bei einer Domänen-Entität geht es darum, ein Domänen-Konzept zu definieren. Wenn es sich bei Ihrer Domänen-Entität nur um eine Datenstruktur handelt, können Sie sie als EF-Entität wiederverwenden, aber das ist nur ein Fall.
Eine DDD-App kennt EF oder ORM nie. Es weiß nur über ein Repository. Daher kennen Ihre Domain Objects (DO) auch nichts über EF. Sie können diese EF-Entitäten als Implementierungsdetail betrachten, ABER ... Sie sollten das NUR tun, nachdem Ihre DOs definiert und ihre Anwendungsfälle implementiert wurden. Sie sollten die Implementierung der Persistenz so weit wie möglich zurückstellen (verwenden Sie In-Memory-Repos (Listen) für devel).
Wenn Sie diesen Punkt erreicht haben, werden Sie wissen, ob Sie Ihren DO für ORM-Zwecke wiederverwenden können oder ob Sie andere Wege benötigen (z. B. ein Erinnerungsstück).
Beachten Sie, dass ein Entwurf einer DO, der von der Domäne gesteuert wird, das Problem der Persistenz berücksichtigen sollte, aber nicht von ihr beeinflusst werden sollte, d. h. Ihre DO nicht gemäß dem DB-Schema entwerfen. Die Persistenzstrategie kann für jede DO unterschiedlich sein und möglicherweise ein ORM beinhalten oder nicht.
Wenn Sie Event Sourcing für eine DO verwenden, ist ORM nicht vorhanden. Gleiches für serialisierte Objekte. Es spielt eine große Rolle, wie ein Objekt von der App verwendet wird (Aktualisierung und Abfrage). Deshalb habe ich gesagt, dass Sie die Persistenzimplementierung aufschieben sollten. Für viele DOs benötigen Sie kein RDBMS (auch wenn Sie es verwenden), so dass eine ORM-Entität eher wie eine KeyValuePair (Id = & gt; serialisierte Daten) aussieht.
Zusammenfassend sind sie verschiedene Dinge für verschiedene Zwecke, die in einigen Fällen (CRUD-Szenarien) identisch aussehen könnten.
Ich würde sagen, sie können gleich sein .
Manchmal müssen zwei Modelle nicht unterstützt werden. Wenn Sie Code zuerst verwenden, modellieren Ihre Entitäten Ihre Domäne, und Ihre Infrastruktur (ORM) trennt Domänen- und Persistenzebenen.
Es kann sinnvoll sein, zwei Modelle beizubehalten , wenn Sie eine ältere Datenbank haben und diese pflegen müssen.
Es gibt zwei weitere SO-Fragen, die hilfreich sein können:
Nun, das ist der Ansatz, den ich verwende. Und ich habe viele andere gesehen, die das gleiche machen. Jetzt benutze ich die Onion-Architektur / das Pattern, um meine Anwendung zu erstellen und alles auf die Domain-Entitäten zu setzen Wann immer ich zum Beispiel den Layer ändern möchte, der mit meiner Datenbank zu tun hat, kann ich das tun, ohne den UI-Layer zu ändern (ASP.NET MVC App, WPF App ... etc) ... Ich schlage vor, dasselbe zu tun.
Warten wir auf andere Beiträge
Ich stimme dem zu, was MikeSW gesagt hat (3. Antwort). Wenn Sie Ihre Domain-Entitäten entwerfen, sollten Sie das tun, ohne sich darum zu kümmern, wer diese Entitäten (ORMs oder andere Technologien, die zu welchem Zweck auch immer dienen) verwenden mind: sie werden wiederverwendbar sein und sie müssen in der Zukunft (hoffentlich) nicht geändert werden
Tags und Links entity-framework architecture entities domain-driven-design