11

データベース エンティティをモデルにマッピングし、ビジネス ロジックを実行する際のベスト プラクティスは何ですか? 私は両方のかなり異なる実装を見てきました。リポジトリ (データ層内) 自体がデータベース エンティティをドメイン モデルにマッピングする役割を果たしている多くの実装に気付きました。たとえば、これを行うリポジトリは次のとおりです。

public IQueryable<Person> GetPersons()
{
      return DbSet.Select(s => new Person
                    {
                        Id = s.Id,
                        FirstName= s.FirstName,
                        Surname= s.Surname,
                        Location = s.Location,
                    });
}

しかし、N 層設計の SO を包括的に検索した結果、特効薬はありませんが、ほとんどの場合、MVC プロジェクトのコントローラー内で手動またはマッパーを使用してマッピングを実行することをお勧めします。また、サービス層はマッピングを実行してはならず、ビジネス ロジックを実行する責任があることも繰り返し述べられています。ここでいくつか質問があります:

  1. エンティティをモデルに、またはその逆にマップする場所に関して、どの方法が適切ですか? リポジトリでこれを行う必要がありますか、それともコントローラーでマッピングを行う必要がありますか?
  2. データベースから取得したエンティティに対して何らかのビジネス ロジックを実行したいとします。たとえば、エンティティの完全な名前を返したり、すべての の年齢を 10 年Person増やしたりします。この操作はどこで実行する必要がありますか。Personモデル自体に?たとえばFullName、フルネームと年齢を計算するモデルにプロパティがありますか? それとも、ビジネス ロジックを実行するために、サービス レイヤー内に何らかのサービスを定義する必要がありますか?

編集

うわー、非常に多くの接近票。申し訳ありませんが、私は十分に包括的に検索していませんでした。ここで提起した「ビジネス ロジックを実行する場所」の問題は、すでに SO やその他の場所で見つけることができます (ときどき不可解に伝えられますが)。

Stephen Walther によるサービス層による検証

スキニーコントローラー

SOに関するもう1つの優れた、しかしより一般的な回答

コントローラーのビジネス ロジックを MVC のどこに置くべきか

サービスはエンティティをビュー モデルにマップしますか

しかし、私が持っていたマッピングの質問に対する標準的な解決策をまだ見つけていません。おそらく私の質問をもっと雄弁に表現できたと思います。そのため、一般的なコンセンサスは、ビジネス ロジックはサービス レイヤーに入り、ドメイン モデルからビュー モデルへのマッピングはコントローラー/プレゼンテーション レイヤーで行う必要があるということです。また、DB エンティティをデータ レイヤー以外のレイヤーに表示しないことをお勧めします。手動で、または Auto Mapper などのマッパーを使用して、エンティティをデータ レイヤーのドメイン モデルにマップすることをお勧めします (これは私が収集したものです)。多くの記事を読む)。私の混乱は、エンティティをドメイン モデルにマッピングし、ドメイン モデルをビュー モデルにマッピングする場所に関する疑問から生じました。しかし、以前にほのめかしたように、質問をもっと明確に表現できたはずです。

4

4 に答える 4

4
  1. エンティティをモデルに、またはその逆にマップする場所に関して、どの方法が適切ですか? リポジトリでこれを行う必要がありますか、それともコントローラーでマッピングを行う必要がありますか?

コントローラではなく、リポジトリでマッピングが行われることを強く望みます。Suhas が回答で述べているように、コントローラーは純粋にコーディネーターとして機能する必要があります。別の方法として、エンティティを渡し、マッピングされたモデルを返すリポジトリ内のマッピング クラスを利用することもできます。これは、Auto Mapperのようなものです。

  1. データベースから取得したエンティティに対して何らかのビジネス ロジックを実行するとします。たとえば、Person エンティティのフル ネームを返したり、すべての Person の年齢を 10 歳ずつ増やしたりします。この操作はどこで実行する必要がありますか。モデル自体に?たとえば、フルネームと年齢を計算するモデルに FullName プロパティがあるでしょうか? それとも、ビジネス ロジックを実行するために、サービス レイヤー内に何らかのサービスを定義する必要がありますか?

可能であれば、サービスでビジネス ロジックを実行します。サービス層が行うべきことをアプリケーションに負担させるのはなぜでしょうか? これはアプリのドメインではなく、サービスのドメインだと思います。また、モデルから連結または派生したプロパティを返すことも悪いことではないと思います。

概要:

  • コントローラーはビューからのリクエストを処理し、それらをリポジトリに転送します
  • リポジトリはデータストアへの導管です
  • サービスはリポジトリからのリクエストを処理し、ビジネス ロジックを処理し、マップされたモデルを返します
于 2013-01-09T15:40:50.387 に答える
1

状況によります...あなたが言ったように、銀の弾丸はありません。各アプローチの長所と短所をリストすることしかできませんが、それでもここで他の誰よりもあなたの要件をよく知っているのはあなたです。時間があれば、この本「エンタープライズアプリケーションアーキテクチャのパターン」を読むことをお勧めします。これにより、さまざまなビジネスロジックとデータソースのアーキテクチャパターン、それらをいつどのように使用するかについて十分に理解できます。何がビジネスレイヤーに行き、何がDALに行くべきか。また、この本は、DALからドメインエンティティにマップする方法の問題を扱っています。長期的には、気が変わってまったく異なるアプローチを選択することもあります。

また、EFCodeFirstやNHibernateなどのCodeFirstメカニズムを提供するORMの使用を検討してください。この場合、すべてのマッピングロジックは透過的です。

于 2013-01-09T16:03:49.750 に答える
1

私は通常、MVC プロジェクト内に小さなサービス レイヤーを作成して、MVC レイヤーが実行する必要がある追加作業を処理します。したがって、あなたの例では、ビジネス層を呼び出してすべてのPersonServicePersonHandlerのエンティティを取得し、すべての人の年齢を 10 年増やすことができます (これはビジネス ロジックではなく、UI が必要とするものであると仮定します)。名と姓を連結してフルネームなどを構築します。コントローラーはこのサービスを呼び出すだけで、舞台裏で何が起こっているのかわかりません。このようにして、コントローラーは理想的にすべきことを実行します-ビューとモデルの間で調整します。

于 2013-01-09T13:12:52.573 に答える