我正在使用存储库模式的项目。我们正在使用Entity Framework从数据库中检索数据。要加载相关数据,我们使用Eager加载,这意味着我们必须明确地包括相关数据。
说我们要拥有所有博客及其相关文章,我们必须写:_dbContext.Blogs.include(b => b.Posts)
。
这样做的缺点是您只能看到存储库类中加载了哪些相关数据。
我试图在下面显示一个示例。这里的问题在类BlogViewModel.cs
中出现,因为您尝试访问blogs.Posts
,但是原始查询中不包含帖子。因此,如果您要获取相关数据,则必须检查查询的来源并查看其是否包含。
Repostiory.cs
public IEnumerable<BlogDbModel> GetBlogs()
{
return _dbContext.Blogs.ToList();
}
Service.cs
public IEnumerable<BlogViewModel> GetBlogs() {
return _repository.Select(x => new BlogViewModel(x));
}
BlogViewModel.cs
public class BlogViewModel {
public BlogViewModel(BlogDbModel blogDbModel) {
Name = blogDbModel.Name;
Posts = blogDbModel.Posts;
}
public string Name { get; set;}
public IEnumberable<Posts> Posts {get; set;}
}
有人对此有一个明智的解决方案吗?如果您尝试访问未包含的数据,是否可能会给出编译错误?
我考虑过的两个选择是:
谢谢
答案 0 :(得分:1)
否,您没有任何选择可以在这种情况下产生编译错误。两种方式的数据都会在运行时加载。
延迟加载
假设您在视图中显示博客,帖子,评论,那么您需要在页面加载时加载所有内容。
启用lazyload
并映射数据层查询中未包含的地图属性时,它将加载相关实体
public BlogViewModel(BlogDbModel blogDbModel)
{
Name = blogDbModel.Name;
Posts = blogDbModel.Posts;
}
如果启用lazyload并执行此操作,则将使用lazyload功能获取此信息。如果发布包含对User
或任何其他对象的引用,它将也加载那些引用。
当您一开始需要所有内容时,不建议您使用lazyload,因为它会额外往返数据库。
可从存储库查询
我会说对视图模型的IQueryable是泄漏抽象。理想情况下,您的数据层应执行这些操作。向Viewmodel提供IQuerable<BlogDbModel>
就像开发人员能够获取1Blogs => Post => User => Accounts1与此相关的任何内容。
恕我直言,我将编写视图所需的数据层方法。
LazyloadingEnabled = false;
public IEnumerable<BlogDbModel> GetBlogs()
{
return _dbContext.Blogs.ToList();
}
public IEnumerable<BlogDbModel> GetBlogsAndPosts()
{
return _dbContext.Blogs.Include("Posts").ToList();
}
//This will fetch only what is needed (You can customize to get columns what is needed)
public IEnumerable<NewCustomDTO> GetBlogsAndPostCount()
{
return _dbContext.Blogs.Select(x=> NewCustomDTO
{
BlogName = x.BlogName,
Count = x.Posts.Count(),
});
}