Entity FrameworkとAnemic Domain Modelの回避


11

ビジネスロジックでは、次のようなメソッドが定義されている場合があります。

User.ResetCourse(Course courseToReset)

問題は、ユーザーとコースの両方がEntity Frameworkプロキシオブジェクトであるということです。つまり、ユーザーまたはコースのいずれかのナビゲーションプロパティにヒットすると、それらのオブジェクトはIQuery可能ではないため、通常どおりに繰り返されるため、データベースに大きなヒットを引き起こす可能性があります。

これを解決するために、署名を次のように変更しました。

User.ResetCourse(MyDBContext db, Course courseToReset)

つまり、データベースに直接クエリを実行して必要な変更を効率的に行うことができますが、データベースコンテキストをビジネスオブジェクトに渡すことは非常に間違っているようです。

その後、ユーザーにサービスレイヤーを移行しました。つまり、次のようなものがあります。

CourseService.ResetForUser(Course courseToReset, User forUser)

このサービスには、作成時に挿入されたDBContextへの参照がありますが、現在のビジネスオブジェクトは、動作のない単なるデータバッグです(つまり、Anemic Domain Model)。

どうすればこれを回避できますか?


11
エンティティフレームワークモデルは実際にはDTOであり、実際にはドメインモデルではないことに気付いたように聞こえます。あなたは実際にDDDをやろうとしていますか?そうでない場合、それはおそらく重要ではありません。
コチェッセ氏16

3
ADM +サービスは、物事の多くのための優れたアーキテクチャである
ユアン・


2
@JohnWuそれは非常に偏った記事です。実際、リッチな例にActive Recordパターンを含めることにより、リッチドメインモデルの「Strawman」バージョンが含まれています。確かに、Active RecordはDDDで支持されておらず、一般的に複雑なアプリケーションには適していません。
RibaldEddie

回答:


7

問題は、そもそもEFオブジェクトをドメインオブジェクトとして使用していることです。EFオブジェクトは、ビジネスモデルではなくデータモデルです。

必要に応じて自由に実行できるビジネスオブジェクトを宣言し、リポジトリで取得および保存する必要があります。リポジトリは、EFエンティティをビジネスエンティティにマップします。EFオブジェクトはリポジトリの外部で使用しないでください。


0

あなたはおそらく次のようなことをすることでそれを避けることができます:

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

とにかく、あなたが私のドリフトをキャッチした場合、またはその効果のために何か。最初に説明した方法でのアプローチはパフォーマンスに関連しており、必ずしもドメインの構造に関連しているわけではないようです。したがって、実際にはサービス層でパフォーマンスの問題を解決することを検討する必要がありますが、ドメイン内で動作を維持できます。より良い回答が必要な場合は、このコンテキストでユーザー/コースをリセットすることの意味を知ることも役立ちます。


-1

従来、これは、IQueryable.Include()を使用して初期クエリで必要な関連付けを積極的にロードするようにEntity Frameworkに指示する各ユースケースのフェッチ戦略を使用することで解決されていました。

Udi Dahanは、Entity Frameworkに適応できる一般的なアプローチを説明する投稿を書きました。

http://udidahan.com/2007/09/16/fetching-strategy-nhibernate-implementation-available/

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.