4

私の質問は、現在取り組んでいるソリューションの階層化に関するものです。私が進んでいる道は層の分離を破っているように感じます。それについてのフィードバックが欲しいです。

私の現在のプロジェクトは、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 をコントローラに直接返すのは良い考えですか? 層の分離を壊していますか? もしそうなら、私の選択肢は何ですか。

ありがとうございました。

4

0 に答える 0