我仍然是实体框架的新手。如果问题是假的,请原谅我:) 我有一个域类,它从数据库中获取一些数据列表:
public IEnumerable<Item> GetItems()
{
return context.Items.ToList();
}
此代码返回数据库中的所有项目 在网站上我使用分页,所以每页只需要10个项目 所以我做了这样的事情:
var model = itemsRepository.GetItems().
Where(x => x.CategoryId == categoryId).
OrderByDescending(x => x.CreatedOnDate).
Skip(0).
Take(pageSize);
现在我看到我在这里做了什么,我从db中取出所有项目并过滤它们 如果我在域中添加新方法并将以下代码放入其中,我会获得一些好处:
return context.Items.Where(x => x.CategoryId == categoryId).
OrderByDescending(x => x.CreatedOnDate).
Skip(0).
Take(pageSize);
答案 0 :(得分:1)
是的,你应该。我假设您使用SQL作为上下文的后端,但是最终使用新方法构造的查询只会将这10条记录拉出来并将它们作为IEnumerable
(延迟执行)返回而不是从数据库中提取所有内容,然后过滤掉前10个结果。
我认为使用延迟执行的第二个(新)方法会更好。
您是否也通过SQL事件探查器看到了性能的提升?
答案 1 :(得分:1)
是。您将获得的好处是,后一种情况下的LINQ查询将转换为SQL并在数据库中执行。因此,您的第一个示例将整个表加载到内存中 - 而第二个示例将在数据库中执行更高效的查询。
基本上,.ToList()
打破了延迟执行 - 但是您可能还有意义返回IQueryable<T>
而不是IEnumerable<T>
,然后在上层处理它 - 这取决于您的要求。另外,请尝试阅读this question and answer。
答案 2 :(得分:1)
您的代码中存在一些问题:
不要在context
课程中使用变量,每次需要时,创建并处理它(使用):
使用(var context = new ...) { //做数据库的东西 }
请勿调用ToList()
,获取所有项目,使用普通分页,然后调用ToList(类似于您的第二个样本,但使用,......)。
答案 3 :(得分:1)
第二种方法的问题是域现在与上下文耦合。这违背了存储库模式的主要目的之一。我建议您在存储库中使用第二种方法,在其中传递您想要检索的页码,然后将它们返回给您。在您的存储库中有类似
的内容public IEnumerable<Item> GetItemsForPage(int pageNumber)
{
return context.Items.Where(x => x.CategoryId == categoryId).
OrderByDescending(x => x.CreatedOnDate).
Skip(pageNumber * pageSize). //Note not always 0
Take(pageSize);
}
在您的域中,您将调用repository.GetItemsForPage()。这为您提供了延迟执行的好处,同时保持了域和上下文的分离。