私のアプリケーションでは、データベース(Entity Framework)とMVCの異なるモデルを使用して、常に物事を分離しています。私もこれらを異なるプロジェクトに分けました。
- Example.Entities -EFのエンティティとそれらにアクセスするためのDBコンテキストが含まれています。
- Example.Models -MVCモデルが含まれています。
- Example.Web -Webアプリケーション。Example.DomainとExample.Modelsの両方に依存します。
ドメインエンティティのように他のオブジェクトへの参照を保持する代わりに、MVCモデルはIDを整数として保持します。
ページのGETリクエストが到着すると、MVCコントローラーはデータベースクエリを実行し、エンティティを返します。ドメインエンティティを取得し、MVCモデルに変換する「コンバーター」メソッドを作成しました。(MVCモデルからドメインエンティティまで)反対のことを行う他の方法があります。その後、モデルはビューに渡され、クライアントに渡されます。
POSTリクエストが到着すると、MVCコントローラーはMVCモデルを取得します。コンバーターメソッドは、これをドメインエンティティに変換します。このメソッドは、属性として表現できない検証も実行し、ドメインエンティティが既に存在する場合、新しいエンティティを取得するのではなく、更新することを確認します。通常、メソッドは次のようになります。
public class PersonConverter
{
public MyDatabaseContext _db;
public PersonEntity Convert(PersonModel source)
{
PersonEntity destination = _db.People.Find(source.ID);
if(destination == null)
destination = new PersonEntity();
destination.Name = source.Name;
destination.Organisation = _db.Organisations.Find(source.OrganisationID);
//etc
return destination;
}
public PersonModel Convert(PersonEntity source)
{
PersonModel destination = new PersonModel()
{
Name = source.Name,
OrganisationID = source.Organisation.ID,
//etc
};
return destination;
}
}
これらの方法を使用することにより、そうでなければ各コントローラーで発生する重複を取り除きます。ジェネリックを使用すると、さらに重複を排除できます。
このように物事を行うことには、複数の利点があります。
- 特定のビューまたはアクションに合わせてモデルをカスタマイズできます。送信すると、多くの異なるエンティティ(個人、組織、住所)を作成する個人のサインアップフォームがあるとします。別のMVCモデルがなければ、これは非常に困難です。
- エンティティでのみ使用できる情報よりも多くの情報をビューに渡す必要がある場合、または2つのエンティティを単一のモデルに結合する必要がある場合、貴重なデータベースモデルは変更されません。
- MVCモデルをJSONまたはXMLとしてシリアル化する場合、このモデルにリンクされている他のすべてのエンティティではなく、シリアル化されている直接のモデルのみを取得します。