4

我的问题与我目前正在研究的解决方案中的分层有关。我觉得我正在走的路正在打破层分离,并希望得到一些反馈。

我当前的项目是一个 ASP.NET MVC4 应用程序,它使用 autofac、EF 5.0 Code First。

我有以下几层:领域、数据、服务和表示

数据层使用一个存储库,该存储库通过 EntityFramework 从数据库返回结果。此存储库返回一个 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<> 对象进行操作。默认情况下,我已经实现了我的 Service 方法来返回 IEnumerbale<> 对象以进行数据检索,因此我的表示层应该始终从服务接收一个 IEnumerable<> 集合。

希望上下文足够清楚。这是我的问题:

我有以下两个域类:

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>();
        }
    }

此外,我在表示层中定义了以下 VideoCategoryModel 类,我需要在 ui 中进行绑定:

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 将很好地解释此查询,它将在数据库上运行一个很好、快速的 Select 查询,使用计数而不是获取所有 Video 对象。这是 GetVideoCategories 实现:

public IQueryable< VideoCategory > GetVideoCategories()
        {
            return videoCategoryRepository.Entities;
        }

我想知道我是否通过将 IQueryable< VideoCategory > (实际上是 EF DbSet)直接返回到我的控制器而不是返回 List<> 对象来打破我的关注点分离和分层。

此外,在 IQueryable<> 对象上调用 ToList() 方法后,将无法将 Count EF 很好地转换为 SQL,因此我再次无法从服务返回 List<VideoCategory>。

所以总结一下这个问题。将 EFDbSet 直接返回给控制器是个好主意吗?我打破了层分离吗?如果是这样,我有什么选择。

谢谢你。

4

0 回答 0