it-swarm.com.de

Ist es empfehlenswert, Entitätsobjekte als Datenübertragungsobjekte zu verwenden?

Ich frage mich, denn wenn ja, warum bietet Entity Framework keine Logik zum Erstellen eines neuen Objekts mit denselben Eigenschaften zum Übertragen von Daten zwischen Ebenen?

Ich verwende die Entitätsobjekte, die ich mit dem Entitätsframework generiere.

30
user2484998

Es liegt an Ihnen.

Die meisten Leute werden Ihnen sagen, dass es keine gute Praxis ist, aber Sie können in einigen Fällen damit durchkommen.

EF hat aus mehreren Gründen nie gut mit DDD gespielt, aber zwei sind hervorzuheben: Sie können keine parametrisierten Konstruktoren für Ihre Entitäten haben und Sie können keine Sammlungen kapseln. DDD stützt sich darauf, da das Domänenmodell sowohl Daten als auch Verhalten enthalten sollte.

In gewisser Weise zwingt EF Sie zu einem anämischen Domänenmodell. In diesem Fall können Sie die Entitäten als DTOs verwenden. Wenn Sie Navigationseigenschaften verwenden, können einige Probleme auftreten, aber Sie können diese Entitäten serialisieren und über das Kabel senden. Es kann jedoch nicht praktisch sein. Sie müssen die Serialisierung für jede Entität steuern, deren Eigenschaften Sie nicht senden müssen. Der einfachere Weg besteht darin, einfach separate Klassen zu entwerfen, die auf die Datenübertragung zugeschnitten sind. Zu diesem Zweck werden Bibliotheken wie AutoMapper erstellt.

Beispiel: Angenommen, Sie haben eine Klasse namens Person mit der folgenden Definition:

public class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime DateOfBirth { get; get; }

    // plus a bunch of other properties relevant about a person
}

Angenommen, Sie möchten irgendwo eine Liste der Mitarbeiter anzeigen, kann es sinnvoll sein, nur die Id, FirstName und LastName zu senden. Sie müssen jedoch alle anderen irrelevanten Eigenschaften senden. Es ist kein so großes Problem, wenn Sie sich nicht für die Größe der Antwort interessieren, aber die allgemeine Idee ist, nur die relevanten Daten zu senden. Auf der anderen Seite können Sie eine API entwerfen, die eine Liste von Personen zurückgibt. In diesem Fall ist möglicherweise das Senden aller Eigenschaften erforderlich. Daher ist es sinnvoll, die Entitäten zu serialisieren und zu senden. In diesem Fall ist das Erstellen einer DTO-Klasse umstritten. Einige Leute mögen es, Entitäten und DTOs zu verwechseln, andere nicht.

Um Ihre aktualisierte Frage zu beantworten, ist EF ein ORM. Seine Aufgabe ist es, Datenbankeinträge Objekten zuzuordnen und umgekehrt. Was Sie mit diesen Objekten vor und nach dem Durchlaufen von EF tun, ist nicht Teil der Bedenken. Es sollte auch nicht sein.

24
devnull

Nein ist es nicht.

Im Idealfall stimmen DTOs mit Ihren Persistenz-Repositorys (auch bekannt als Ihre Datenbanktabellen) überein.

Aber Ihre Business-Klassen passen nicht unbedingt zusammen. Möglicherweise benötigen Sie zusätzliche Klassen oder getrennte oder verbundene Klassen zu dem, was Sie in der Datenbank haben. Wenn Ihre Anwendung klein ist, treten diese Probleme möglicherweise nicht wirklich auf. Bei mittleren bis großen Anwendungen tritt dies jedoch häufig auf.

Eine andere Sache ist, dass DTOs Teil der Domäne dessen sind, was sich mit Persistenz befasst, während Ihre Business-Schicht nichts über sie wissen sollte.

Nein, das ist eine schlechte Praxis.

Einige Gründe:

  1. Neue Entitätsfelder befinden sich standardmäßig im Dto. Die Verwendung der Entität bedeutet, dass alle Informationen verfügbar sind, um standardmäßig verwendet zu werden. Dies kann dazu führen, dass Sie sinnvolle Informationen preisgeben oder zumindest Ihren API-Vertrag mit vielen Informationen aufblähen, die nicht für diejenigen verwendet werden, die die API verwenden. Natürlich können Sie Felder mit einigen Anmerkungen (wie @JsonIgnore Aus der Java Welt) ignorieren, aber dies führt zum nächsten Problem ...
  2. Viele Anmerkungen/Bedingungen/Steuerelemente für die Entität. Sie müssen steuern, was Sie an Dto senden möchten, wenn sich ein Attributname ändert (dies bricht den Vertrag), ein Attribut hinzufügen, das nicht von der Entität stammt, die Reihenfolge der Attribute usw. Bald sehen Sie Ihr einfaches Entität mit vielen Anmerkungen, zusätzlichen Feldern und jedes Mal wird es schwieriger zu verstehen sein, was passiert.
  3. weniger Flexibilität. Mit einem Dto können Sie die Informationen in mehrere Klassen aufteilen, die Attributnamen ändern, neue Attribute hinzufügen usw. Mit einer Entität wie Dto können Sie dies nicht so einfach tun.
  4. nicht optimiert. Ihre Entität wird immer größer sein als ein einfaches Dto. Sie müssen also immer mehr Informationen ignorieren/serialisieren und wahrscheinlich mehr unnötige Informationen übertragen.
  5. Faule Probleme. Wenn Sie unter Verwendung der Entität einiger Frameworks (z. B. Hibernate) versuchen, Informationen abzurufen, die zuvor nicht verzögert in eine Datenbanktransaktion geladen wurden, wird der ORM-Proxy nicht an die Transaktion angehängt und Sie erhalten eine Art "verzögerte Ausnahme". Nur um eine get -Methode der Entität aufzurufen.

Es ist also einfacher und sicherer, ein Mapper-Tool zu verwenden, das Sie bei diesem Job unterstützt und die Entitätsfelder einem Dto zuordnet.

6
Dherik

Es ist eigentlich eine sehr schlechte Idee. Martin Fowler hat ein Artikel über lokale DTOs .

Kurz gesagt, DTO Pattern wurde zum Übertragen von Daten außerhalb des Prozesses verwendet, z. B. über den Draht und nicht zwischen Ebenen innerhalb desselben Prozesses.

5

Um das zu vervollständigen, was @Dherik gesagt hat, sind die Hauptprobleme bei der Verwendung von Entitätsobjekten als Datenübertragungsobjekte:

  1. Bei einer Transaktion gehen Sie das Risiko ein, Änderungen an Ihrer Entität festzuschreiben, da Sie diese als DTO verwenden (selbst wenn Sie die Entität der Sitzung in einer Transaktion trennen können, müssen Sie diesen Status meistens vorher überprüfen Änderungen an Ihrem Entity-DTO und stellen Sie sicher, dass Sie sich nicht in einer Transaktion befinden oder dass die Sitzung geschlossen wurde, wenn Sie nicht möchten, dass die Änderungen beibehalten werden.

  2. Die Größe der Daten, die Sie zwischen dem Client und dem Server gemeinsam nutzen: Manchmal möchten Sie nicht den gesamten Inhalt einer Entität an den Client senden, um die Größe der Antwort der Anforderung zu minimieren. Das Trennen des DTO von der Entität ist flexibler, um die Daten zu spezialisieren, die Sie in bestimmten Anwendungsfällen senden möchten.

  3. Sichtbarkeit und Wartung: Sie müssen Ihre jpa/Hibernate-Annotationen in den Feldern Ihrer Entität verwalten und die Jackson-Annotationen beibehalten, um sie in json an derselben Stelle zu serialisieren (auch wenn Sie sie von der Entity-Implementierung trennen können, indem Sie sie in die von der geerbte Schnittstelle einfügen Entität). Wenn Sie dann Ihren DTO-Inhalt beim Hinzufügen eines neuen Felds ändern, kann eine andere Person wahrscheinlich denken, dass es sich um ein Feld der Entität handelt, also um ein Feld der betreffenden Tabelle in Ihrer Datenbank (selbst wenn Sie den @Transient Verwenden können). Anmerkung zu allen DTO-Feldern für den Fall ..!).

Meiner Meinung nach erzeugt es Lärm, wenn Sie die Entität lesen, aber meine Meinung ist sicherlich subjektiv.

1