Entity Framework und Vermeidung des anämischen Domänenmodells


11

In unserer Geschäftslogik haben wir gelegentlich Methoden wie diese definiert:

User.ResetCourse(Course courseToReset)

Das Problem ist, dass sowohl Benutzer als auch Kurs Entity Framework-Proxyobjekte sind. Dies bedeutet, dass das Aufrufen der Navigationseigenschaften für Benutzer oder Kurs einen großen Treffer für die Datenbank verursachen kann, da diese Objekte nicht IQuery-fähig sind und daher normal durchlaufen werden.

Um dies zu lösen, haben wir die Signatur geändert in:

User.ResetCourse(MyDBContext db, Course courseToReset)

Dies bedeutet, dass wir die Datenbank direkt abfragen können, um die erforderlichen Änderungen auf effiziente Weise vorzunehmen, aber die Übergabe des Datenbankkontexts an ein Geschäftsobjekt scheint einfach so falsch.

Wir haben später eine Service-Schicht auf den Benutzer migriert, was bedeutet, dass wir Folgendes haben:

CourseService.ResetForUser(Course courseToReset, User forUser)

Dieser Service enthält einen Verweis auf den DBContext, der bei der Erstellung eingefügt wurde. Jetzt sind unsere Geschäftsobjekte nur noch Datentaschen ohne Verhalten (dh ein anämisches Domänenmodell).

Wie können wir das vermeiden?


11
Klingt so, als hätten Sie gerade die Erkenntnis getroffen, dass Entity-Framework-Modelle tatsächlich DTOs sind und überhaupt kein Domain-Modell. Versuchen Sie tatsächlich, DDD zu machen? Wenn nicht, spielt es wahrscheinlich keine Rolle.
Herr Cochese

3
ADM plus Services ist eine gute Architektur für viele Dinge
Ewan


2
@ JohnWu das ist ein sehr voreingenommener Artikel. In der Tat enthält es eine "Strawman" -Version eines Rich-Domain-Modells, indem das Active Record-Muster in das Rich-Beispiel aufgenommen wird. Sicherlich wird Active Record in DDD nicht unterstützt und ist im Allgemeinen eine schlechte Wahl für komplexe Anwendungen.
RibaldEddie

Antworten:


7

Das Problem ist, dass Sie in erster Linie EF-Objekte als Domänenobjekte verwenden. EF-Objekte sind Datenmodelle, KEINE Geschäftsmodelle.

Sie müssen Geschäftsobjekte deklarieren, die Ihnen die Freiheit geben, das zu tun, was Sie benötigen, und sie dann abrufen und in einem Repository speichern. Ihr Repository ordnet die EF-Entitäten Ihren Geschäftsentitäten zu. EF-Objekte sollten niemals außerhalb Ihrer Repositorys verwendet werden.


0

Sie können es wahrscheinlich vermeiden, indem Sie etwas tun wie:

CourseService.prepareForUserCourseReset(DBContext db);
User.reset();
Course.reset();
CourseService.completeUserCourseReset(DBContext db);

Oder zumindest etwas in diesem Sinne, wenn Sie meinen Drift bemerken. Es klingt so, als ob der Ansatz, den Sie mit der ursprünglich beschriebenen Art und Weise verfolgen, leistungsbezogen ist und nicht unbedingt mit der Struktur der Domäne zusammenhängt. Sie sollten also in Betracht ziehen, das Leistungsproblem in der Service-Schicht zu lösen, können aber das Verhalten in der Domäne beibehalten. Es wäre hilfreich zu wissen, was es bedeutet, den Benutzer / Kurs auch in diesem Zusammenhang zurückzusetzen, wenn Sie eine bessere Antwort wünschen.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.