ある場合、なぜエンティティフレームワークは、レイヤー間でデータを転送するために同じプロパティを持つ新しいオブジェクトを作成するロジックを提供しないのでしょうか。
エンティティフレームワークで生成したエンティティオブジェクトを使用しています。
それはあなた次第です。
ほとんどの人はそれは良い習慣ではないと言いますが、場合によってはそれでうまくいくことがあります。
EFは、複数の理由でDDDをうまく使用できませんでしたが、2つ目立っています。エンティティにパラメーター化されたコンストラクターを持たせたり、コレクションをカプセル化したりすることはできません。ドメインモデルにはデータと動作の両方を含める必要があるため、DDDはそれに依存しています。
ある意味で、EFは貧血ドメインモデルを強制するため、この場合はエンティティをDTOとして使用できます。ナビゲーションプロパティを使用する場合、いくつかの問題が発生する可能性がありますが、それらのエンティティをシリアル化してネットワーク経由で送信できます。しかし、それは実際的ではないかもしれません。送信する必要のないプロパティを持つ各エンティティのシリアル化を制御する必要があります。より簡単な方法は、データ転送用に調整された個別のクラスを単純に設計することです。 AutoMapper のようなライブラリがこの目的で作成されます。
例:次の定義のPerson
というクラスがあるとします。
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
}
従業員のリストをどこかに表示したい場合、Id
、FirstName
、LastName
のみを送信するのが現実的です。ただし、他のすべての無関係なプロパティを送信する必要があります。応答のサイズを気にしない場合はそれほど大きな問題ではありませんが、関連するデータのみを送信するのが一般的な考え方です。一方、人物のリストを返すAPIを設計する場合は、すべてのプロパティを送信する必要があるため、エンティティをシリアル化して送信するのが合理的です。この場合、DTOクラスの作成は議論の余地があります。エンティティとDTOの混同が好きな人もいれば、そうでない人もいます。
更新された質問に答えるために、EFはORMです。その仕事は、データベースレコードをオブジェクトに、またはその逆にマッピングすることです。 EFを通過する前後にこれらのオブジェクトをどのように処理するかは、EFの問題の一部ではありません。それもそうではありません。
いいえそうではありません。
理想的には、DTOは永続リポジトリ(別名、データベーステーブル)と一致します。
ただし、ビジネスクラスは必ずしも一致しません。データベースにあるものに対して、追加のクラス、または分離されたクラス、または結合されたクラスが必要になる場合があります。アプリケーションが小さい場合、この種の問題は実際には発生しない可能性がありますが、中規模から大規模のアプリケーションでは、これが頻繁に発生します。
もう1つは、ビジネスレイヤーがDTOについて何も知らなくても、DTOは永続性を扱うもののドメインの一部であることです。
いいえ、それは悪い習慣です。
いくつかの理由:
@JsonIgnore
など)を使用してフィールドを無視できますが、これは次の問題につながります...get
メソッドを呼び出すだけです。したがって、エンティティフィールドをDtoにマッピングして、このジョブを支援するために、ある種のマッパーツールを使用する方が簡単で安全です。
それは実際には非常に悪い考えです。 Martin Fowlerには ローカルDTOに関する記事 があります。
要するに、DTO
パターンは、同じプロセス内のレイヤー間ではなく、ネットワーク経由など、プロセス外のデータ転送に使用されました。
@Dherikが言ったことを完了するために、エンティティオブジェクトをデータ転送オブジェクトとして使用することの主な問題は次のとおりです。
トランザクションでは、DTOとして使用するため、エンティティに加えられた変更をコミットするリスクがあります(トランザクションでセッションのエンティティをデタッチできる場合でも、ほとんどの場合、前にこの状態を確認する必要がありますエンティティDTOに変更を加え、トランザクション内にないこと、または変更を永続化したくない場合はセッションが閉じられていることを確認します)。
クライアントとサーバー間で共有するデータのサイズ:エンティティのすべてのコンテンツをクライアントに送信して、リクエストの応答のサイズを最小限にしたくない場合があります。エンティティからDTOを分離すると、特定のユースケースで送信するデータを特化できるように、より柔軟になります。
可視性とメンテナンス:エンティティのフィールドでjpa/hibernateアノテーションを管理し、同じ場所でjsonでシリアル化するためにジャクソンアノテーションを維持する必要があります(エンティティ実装から分離して、インターフェースによって継承されたインターフェースに配置できる場合でも)エンティティ)。次に、新しいフィールドを追加するときにDTOコンテンツを変更すると、別の人はおそらくそれがエンティティのフィールドであると考えることができるため、データベースで関係するテーブルのフィールド(@Transient
ケースのすべてのDTOフィールドの注釈..!)。
私の意見では、エンティティを読むときにノイズが発生しますが、私の意見は確かに主観的です。