我编写了一个分页函数,我希望它可以进行EF安全分页。看来这个函数在分页之前执行EF查询,我想要它做的是将分页推迟到数据库。我以为IEnumerable会安全,但似乎不是。这里发生了什么?
private IEnumerable<T> PageList<T>(IEnumerable<T> list, PaginationOptions options)
{
return list.Skip((options.Page - 1) * options.ResultsPerPage).Take(options.ResultsPerPage);
}
如果我将此测试作为函数vs实际函数调用,则生成包含分页信息的SQL,而另一个(函数)则不生成。
var pagedStuff = this.PageList(activities, options); // doesnt create correct query
var pagedStuff = activities.Skip((options.Page - 1) * options.ResultsPerPage).Take(options.ResultsPerPage);
P.S。我使用IEnumerable,因为有时这个函数用于普通列表。
答案 0 :(得分:2)
我使用
IEnumerable
,因为有时此函数用于普通List
s
您可能还需要考虑进行IQueryable
重载:
private IQueryable<T> PageList<T>(IQueryable<T> list, PaginationOptions options)
{
return list.Skip((options.Page - 1) * options.ResultsPerPage).Take(options.ResultsPerPage);
}
问题在于,由于输入是IEnumerable
,因此在应用分页之前正在执行查询,因此您将获得所有记录并在Linq-中完成分页到对象。
使用IQueryable
会延迟执行查询,直到在之后应用分页。
答案 1 :(得分:1)
您正在调用IEnumerable.Skip/Take
而不是IQueryable.Skip/Take
。
尝试使用AsQueryable
方法:
return list.AsQueryable()
.Skip((options.Page - 1) * options.ResultsPerPage)
.Take(options.ResultsPerPage);