我的问题与我目前正在研究的解决方案中的分层有关。我觉得我正在走的路正在打破层分离,并希望得到一些反馈。
我当前的项目是一个 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 直接返回给控制器是个好主意吗?我打破了层分离吗?如果是这样,我有什么选择。
谢谢你。