我已经在本教程的帮助下完成了分页 Paging
我正在使用视图模型,我的问题是,当我点击页面编号时,它将转到“ActionMethod”并从数据库中检索2k记录,并过滤显示在其中的10条记录(ViewModel.Summaries.ToPagedList(page, pagesize);
)视图。如果我点击下一页编号,则会发生相同的周期。
那么它是否会降低页面的性能?因为它每次都会访问数据库并获取2k记录然后过滤?
ActionMethod:
public ActionResult Details(int page=1,int pagesize=10)
{
ViewModel ViewModel = this.Gateway.GetDetails(Id);//2k records r getting from DB
ViewModel.SummariesPaged = ViewModel.Summaries.ToPagedList(page, pagesize);
return View("Details", ViewModel);
}
查看型号:
public class ViewModel
{
public List<SummaryModel> Summaries { get; set; }
public PagedList.IPagedList<SummaryModel> SummariesPaged { get; set;
}
}
答案 0 :(得分:0)
您应该只从您要显示的数据库中获取记录,您可以创建如下的方法。
public IList<SomeType> ToPagedList(int pageNo, int pageSize)
{
return db.Summaries.Skip((pageNo-1) * pageSize).Take(pageSize).ToList();
}
<强>更新强>
抱歉,我没有注意到您已经在使用PagedList.Mvc
,因此无需创建上述方法。
您只需要在IQuerable上调用ToPageList方法,而无需调用ToList
方法。当linq遇到ToList
方法时,它会对数据库执行查询,然后在查询后会导致 linq到对象而不是 linq到sql 。
所以这里有解决方案。使用如下。
db.Summaries.ToPageList(page, pageSize);
如果需要,您可以应用过滤器并排序摘要,但在ToPagedList方法之前不要调用列表。
答案 1 :(得分:0)
您的问题提出了不同详细程度的几个答案。
首先,当你只需要10个时,PagedList.Mvc
实际读取2000条记录吗?答案是不。实体框架支持方法IQueryable<T>.Take
和IQueryable<T>.Skip
,并将它们转换为SQL结构,如LIMIT
,TOP
,带有ROW_NUMBER
的CTE,OFFSET FETCH
和其他(取决于引擎及其版本)。因此,您应该使用文档中描述的PagedList.Mvc
。
第二,当你只需要10个时,SQL服务器是否实际处理了2000个记录?答案是肯定的。服务器使用B树来存储表和索引。尽管B-tree允许快速获取 n -th记录,但此功能意味着开销,并且未在大多数流行的现代服务器中实现。我只看到了Berkley DB中的实现,并且在那里启用/禁用了此功能。
因此,如果您要求服务器为您提供1,000,000到1,000,010之间的数字记录,它实际上会扫描并跳过1,000,000条记录。
如果表中的记录数量不是很大(比如不到一百万),这不是问题。但是如果你有10或1亿条记录,你可能会遇到性能问题。