如何使用 PagedList 进行真正的分页?
How do I make a real pagination using PagedList?
我在数据库中有一个 table,有 10.000 条记录,我想使用 PagedList 对其进行分页。问题是加载了所有记录,然后 PagedList 对它们进行分页,速度变得非常慢。我想做一个真正的分页,例如返回每 20 条记录直到 10.000 并在视图中显示它们,但我做不到。
我该怎么做?有什么例子吗?
模型搜索
public class SearchUsuario
{
public IPagedList<ViewUsuario> lista { get; set; }
public SearchUsuario(){
lista = new List<ViewUsuario>().ToPagedList(1, 50);
}
}
Model ViewUsuario
public class ViewUsuario
{
public String nome { get; set; }
}
通用 DAO
//returns all records
public IQueryable<T> GetAll()
{
IQueryable<T> query = context.Set<T>();
return query;
}
控制器
public ActionResult view(int? page)
{
int pageNumber = page ?? 1;
int pageSize = 10;
SearchUsuario search = new SearchUsuario();
IQueryable<Usuario> lista = new UsuarioDAO().GetAll(); //returns all records
List<ViewUsuario> listaModel = new List<ViewUsuario>();
foreach(Usuario u in lista){
Debug.WriteLine(u.nome);
ViewUsuario view = new ViewUsuario();
view.nome = u.nome;
listaModel.Add(view);
}
search.lista = listaModel.ToPagedList(pageNumber, pageSize);
return View(search);
}
查看
@using PagedList.Mvc
@model SearchUsuario
....
<table id="grid" class="table table-striped table-hover" cellspacing="0">
<thead>
<tr>
<th>Nome</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Nome</th>
</tr>
</tfoot>
<tbody>
@foreach (ViewUsuario m in Model.lista){
<tr>
<td>@Html.DisplayFor(i => m.nome)</td>
</tr>
}
</tbody>
</table>
....
Pagina @Model.lista.PageNumber de @Model.lista.PageCount
@Html.PagedListPager(Model.lista, page => Url.Action("view", new{ page = page }))
.ToPagedList()
方法内部调用.Skip()
和.Take()
将结果集限制为指定的记录数。但是,它旨在获取数据模型的 IQueryable<T>
,而不是为视图模型设计的。
您的问题是,您使用 IQueryable<Usuario>
并使用循环为数据库中的每条记录生成视图模型,因此您不仅将 10,000 条记录下载到内存中,还创建了 10,000 个视图模型在内存中(然后你扔掉了其中的 9,990 个)
根据您显示的代码,您不需要视图模型。相反,您可以简单地使用
public ActionResult view(int? page)
{
int pageNumber = page ?? 1;
int pageSize = 10;
IQueryable<Usuario> lista = new UsuarioDAO().GetAll();
SearchUsuario search = new SearchUsuario
{
lista = lista.ToPagedList(pageNumber, pageSize);
};
return View(search);
}
并将SearchUsuario
中的属性改为
public IPagedList<Usuario> lista { get; set; }
ToPagedList()
方法现在只会下载视图中所需的 10 条记录。
对于确实需要视图模型的情况,您需要使用 StaticPagedList
方法并将记录总数传递给它,以便正确呈现视图中的页码按钮。这意味着第二次数据库调用以获取记录的 .Count()
,但这通常非常快
public ActionResult view(int? page)
{
int pageNumber = page ?? 1;
int pageSize = 10;
// Get the count of all records
int totalRecords = IQueryable<Usuario> lista = new UsuarioDAO().GetAll().Count();
// Get just the records to be displayed using .Skip() and .Take()
// and project into your view model
IEnumerable<ViewUsuario> lista = new UsuarioDAO().GetAll()
.OrderBy(u => u.nome).Skip(pageSize * pageNumber).Take(pageSize)
.Select(x => new ViewUsuario
{
nome = x.nome,
....
});
SearchUsuario search = new SearchUsuario
{
lista = new StaticPagedList<ViewUsuario>(lista, pageNumber, pageSize, totalRecords);
}
return View(search);
}
我在数据库中有一个 table,有 10.000 条记录,我想使用 PagedList 对其进行分页。问题是加载了所有记录,然后 PagedList 对它们进行分页,速度变得非常慢。我想做一个真正的分页,例如返回每 20 条记录直到 10.000 并在视图中显示它们,但我做不到。
我该怎么做?有什么例子吗?
模型搜索
public class SearchUsuario
{
public IPagedList<ViewUsuario> lista { get; set; }
public SearchUsuario(){
lista = new List<ViewUsuario>().ToPagedList(1, 50);
}
}
Model ViewUsuario
public class ViewUsuario
{
public String nome { get; set; }
}
通用 DAO
//returns all records
public IQueryable<T> GetAll()
{
IQueryable<T> query = context.Set<T>();
return query;
}
控制器
public ActionResult view(int? page)
{
int pageNumber = page ?? 1;
int pageSize = 10;
SearchUsuario search = new SearchUsuario();
IQueryable<Usuario> lista = new UsuarioDAO().GetAll(); //returns all records
List<ViewUsuario> listaModel = new List<ViewUsuario>();
foreach(Usuario u in lista){
Debug.WriteLine(u.nome);
ViewUsuario view = new ViewUsuario();
view.nome = u.nome;
listaModel.Add(view);
}
search.lista = listaModel.ToPagedList(pageNumber, pageSize);
return View(search);
}
查看
@using PagedList.Mvc
@model SearchUsuario
....
<table id="grid" class="table table-striped table-hover" cellspacing="0">
<thead>
<tr>
<th>Nome</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Nome</th>
</tr>
</tfoot>
<tbody>
@foreach (ViewUsuario m in Model.lista){
<tr>
<td>@Html.DisplayFor(i => m.nome)</td>
</tr>
}
</tbody>
</table>
....
Pagina @Model.lista.PageNumber de @Model.lista.PageCount
@Html.PagedListPager(Model.lista, page => Url.Action("view", new{ page = page }))
.ToPagedList()
方法内部调用.Skip()
和.Take()
将结果集限制为指定的记录数。但是,它旨在获取数据模型的 IQueryable<T>
,而不是为视图模型设计的。
您的问题是,您使用 IQueryable<Usuario>
并使用循环为数据库中的每条记录生成视图模型,因此您不仅将 10,000 条记录下载到内存中,还创建了 10,000 个视图模型在内存中(然后你扔掉了其中的 9,990 个)
根据您显示的代码,您不需要视图模型。相反,您可以简单地使用
public ActionResult view(int? page)
{
int pageNumber = page ?? 1;
int pageSize = 10;
IQueryable<Usuario> lista = new UsuarioDAO().GetAll();
SearchUsuario search = new SearchUsuario
{
lista = lista.ToPagedList(pageNumber, pageSize);
};
return View(search);
}
并将SearchUsuario
中的属性改为
public IPagedList<Usuario> lista { get; set; }
ToPagedList()
方法现在只会下载视图中所需的 10 条记录。
对于确实需要视图模型的情况,您需要使用 StaticPagedList
方法并将记录总数传递给它,以便正确呈现视图中的页码按钮。这意味着第二次数据库调用以获取记录的 .Count()
,但这通常非常快
public ActionResult view(int? page)
{
int pageNumber = page ?? 1;
int pageSize = 10;
// Get the count of all records
int totalRecords = IQueryable<Usuario> lista = new UsuarioDAO().GetAll().Count();
// Get just the records to be displayed using .Skip() and .Take()
// and project into your view model
IEnumerable<ViewUsuario> lista = new UsuarioDAO().GetAll()
.OrderBy(u => u.nome).Skip(pageSize * pageNumber).Take(pageSize)
.Select(x => new ViewUsuario
{
nome = x.nome,
....
});
SearchUsuario search = new SearchUsuario
{
lista = new StaticPagedList<ViewUsuario>(lista, pageNumber, pageSize, totalRecords);
}
return View(search);
}