私の質問は、現在取り組んでいるソリューションの階層化に関するものです。私が進んでいる道は層の分離を破っているように感じます。それについてのフィードバックが欲しいです。
私の現在のプロジェクトは、autofac、EF 5.0 Code First を使用する ASP.NET MVC4 アプリです。
次のレイヤーがあります: ドメイン、データ、サービス、およびプレゼンテーション
データ層は、EntityFramework を介して DB から結果を返すリポジトリを使用します。このリポジトリは、取得した結果のセットとして IQueryable<> オブジェクトを返します。(これは、EF の DbSet<> が IQueryable<> から派生しているためです)。
public interface IRepository<T> where T : BaseEntity
{
T GetById(object id);
void Insert(T entity);
void Update(T entity);
void Delete(T entity);
IQueryable<T> Entities { get; }
}
サービス層は前述のリポジトリを利用するため、IQueryable<> オブジェクトで動作します。デフォルトでは、データ取得のために IEnumerbale<> オブジェクトを返す Service メソッドを実装しているため、プレゼンテーション層は常にサービスから IEnumerable<> コレクションを受け取る必要があります。
うまくいけば、コンテキストは十分に明確です。これは私の問題です:
次の 2 つのドメイン クラスがあります。
public class Video
{
public virtual string Title { get; set; }
public virtual VideoCategory VideoCategory { get; set; }
public int VideoCategoryId { get; set; }
}
public class VideoCategory
{
public string Title { get; set; }
public string Description { get; set; }
public List<Video> Videos { get; set; }
public VideoCategory()
{
Videos = new List<Video>();
}
}
また、UI でバインドするために必要な、プレゼンテーション層で定義された次の VideoCategoryModel クラスがあります。
public class VideoCategoryModel
{
public string Title { get; set; }
public string Description { get; set; }
public int VideoCount { get; set; }
}
ご覧のとおり、ビデオ カテゴリを表すオブジェクトのコレクションと、各カテゴリのビデオの数を取得したいと考えています。もちろん、すべての Video オブジェクトを取得せずにこれを実行したいと考えています。これを実現するために、サービス メソッドは IQueryable< VideoCategory > をプレゼンテーションに返し、コントローラーで次のようにクエリできるようにします。
var convertedResults = from videoCategory in service.GetVideoCategories()
select new VideoCategoryModel()
{
Title = videoCategory.Title,
Description = videoCategory.Description,
VideoCount = videoCategory.Videos.Count
};
このクエリは EF によって適切に解釈され、すべての Video オブジェクトをフェッチする代わりにカウントを使用して、DB で優れた高速の Select クエリを実行します。これは GetVideoCategories の実装です。
public IQueryable< VideoCategory > GetVideoCategories()
{
return videoCategoryRepository.Entities;
}
オブジェクトの List<> を返すのではなく、IQueryable< VideoCategory > (実際には EF DbSet) をコントローラーに直接返すことで、懸念と階層化の分離を破っているかどうかを知りたいです。
また、IQueryable<> オブジェクトで ToList() メソッドを呼び出した後、カウント EF を取得することが不可能になり、SQL に適切に変換されるため、サービスから List< VideoCategory > を返すことができません。
というわけで質問を要約します。EFDbSet をコントローラに直接返すのは良い考えですか? 層の分離を壊していますか? もしそうなら、私の選択肢は何ですか。
ありがとうございました。