次の単純な POCO、国と州を想定します。
public partial class Country
{
public Country()
{
States = new List<State>();
}
public virtual int CountryId { get; set; }
public virtual string Name { get; set; }
public virtual string CountryCode { get; set; }
public virtual ICollection<State> States { get; set; }
}
public partial class State
{
public virtual int StateId { get; set; }
public virtual int CountryId { get; set; }
public virtual Country Country { get; set; }
public virtual string Name { get; set; }
public virtual string Abbreviation { get; set; }
}
ここで、次のような単純なリポジトリがあるとします。
public partial class CountryRepository : IDisposable
{
protected internal IDatabase _db;
public CountryRepository()
{
_db = new Database(System.Configuration.ConfigurationManager.AppSettings["DbConnName"]);
}
public IEnumerable<Country> GetAll()
{
return _db.Query<Country>("SELECT * FROM Countries ORDER BY Name", null);
}
public Country Get(object id)
{
return _db.SingleById(id);
}
public void Add(Country c)
{
_db.Insert(c);
}
/* ...And So On... */
}
通常、私の UI では、すべての子 (状態) を表示するわけではありませんが、集計数は表示します。したがって、私の国のリスト ビュー モデルは次のようになります。
public partial class CountryListVM
{
[Key]
public int CountryId { get; set; }
public string Name { get; set; }
public string CountryCode { get; set; }
public int StateCount { get; set; }
}
基になるデータ プロバイダー (Entity Framework、NHibernate、PetaPoco など) を UI レイヤーで直接使用している場合、次のようなことを簡単に行うことができます。
IList<CountryListVM> list = db.Countries
.OrderBy(c => c.Name)
.Select(c => new CountryListVM() {
CountryId = c.CountryId,
Name = c.Name,
CountryCode = c.CountryCode,
StateCount = c.States.Count
})
.ToList();
しかし、リポジトリまたはサービス パターンを使用している場合は、データ レイヤーへの直接アクセスを抽象化します。私のオプションは次のとおりです。
データが入力された States コレクションで Country を返し、UI レイヤーにマップします。このアプローチの欠点は、実際に必要な量よりも多くのデータを返すことです。
-また-
すべてのビュー モデルを共通 dll ライブラリに入れ (MVC アプリの Models ディレクトリに置くのではなく)、リポジトリを展開して、ドメイン pocos だけでなく特定のビュー モデルを返します。このアプローチの欠点は、UI 固有のもの (MVC データ検証注釈) を以前のクリーンな POCO にリークしていることです。
-また-
他のオプションはありますか?
このようなことをどのように処理していますか?