如何使用PagedList进行真正的分页?

时间:2018-02-06 18:29:15

标签: asp.net-mvc pagedlist

我在数据库上有一个表有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);
    }
}

模型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 }))

1 个答案:

答案 0 :(得分:2)

.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);
}