ASP.NET MVC Webgrid高效分页

时间:2012-06-19 12:27:57

标签: asp.net-mvc pagination webgrid skip-take

我有一个ASP.NET MVC 4项目和一个SQL View(vvItem)。 ItemController

    MVCAppEntities db = new MVCAppEntities();
    public ActionResult Index()
    {
        var itemqry = db.vvItem.OrderBy(s => s.name);
        //var pageditems = itemqry.Skip(10).Take(20); // 25 seconds
        return View(itemqry.ToList()); // 88 seconds
    }

Index.cshtml查看

@model IEnumerable<MVCApplication1.Models.vvItem>
@{
    var norows = 20;
    var grid = new WebGrid(Model, canPage: true, rowsPerPage: norows);
    grid.Pager(WebGridPagerModes.NextPrevious);  
    @grid.GetHtml(tableStyle: "table",  headerStyle: "header", columns: grid.Columns(
          grid.Column(columnName: "name", header: "Name", canSort: true),
          grid.Column(columnName: "quantity", header: "Quantity", canSort: true),  
          grid.Column(columnName: "code", header: "Code", canSort: true),
          grid.Column(columnName: "Price", header: "Price", canSort: true),
          ))}

在vvItem中,我有近400000条记录。我认为webgrid Pager只会加载(Take())显示的记录,如果我要转到下一页,它会知道Skip()的第一条记录。

:如何有效地制作视图以仅加载显示的记录?

我找到了2个解决方案:JSON versionNerdDinner

我不太擅长JSON所以我尝试了NerdDinner解决方案。就像我的评论一样 //var pageditems = itemqry.Skip(10).Take(20); itemqry已经加载了所有记录,并且需要花费大量时间才能加载。

Q2 :我现在如何进行分页?我需要修改页面号。来自Index方法。

public ActionResult Index(int? page, string filter1 = " ", string filter2 = " ")

4 个答案:

答案 0 :(得分:2)

我制作了一个SQL存储过程

CREATE PROCEDURE SkipTake 
    @pagNo int, 
    @pageSize int
AS    
    select *
    from (select *, row_number() over (order by COD) as rn 
          from vvSTOC
         ) as T
    where T.rn between (@pagNo - 1) * @pageSize + 1 and @pagNo * @pageSize

我在功能导入的EF模型中添加了这个sp,以便它返回一个实体(vvSTOC)

    public ActionResult Index(int? page)
    {
        const int pageSize = 20;
        return View(db.spSkipTake(page, pageSize).ToList());
    }

答案 1 :(得分:1)

只要itemqry是IEnumerable或IQueryable类型,它就不应该立即执行查询。你可以把它作为一个IQueryable投射如下吗?

public ActionResult Index()
{
    IQueryable<vvItem> itemQry = db.vvItem;
    return View(itemQry.OrderBy(s => s.name).Skip(10).Take(20).ToList());
}

如果itemqry是正确的类型,则在调用.ToList()将其转换为IList类型之前,它不会被执行。检查正在生成的SQL以确定。

答案 2 :(得分:0)

public ActionResult Index(int? pageIndex)
{
   int pageSize = 20;
   var itemIndex = ((pageIndex??1) -1) * pageSize;

    return View(db.vvItem.OrderBy(s => s.name).Skip(itemIndex).Take(pageSize).ToList()); 
}

答案 3 :(得分:0)

谢谢你。

我调整了它来处理我的SP中的一些输入参数来控制PageSize,PageNumber,SortIndex和SortOrder:

declare @sql nvarchar(1000) = '
select * from
(
    select *, row_number() over(order by '+@SortIndex+' '+@SortOrder+') as RowNumber from #Results
) as T
where T.RowNumber between ('+@PageNumber+' - 1) * '+@PageSize+' + 1 and '+@PageNumber+' * '+@PageSize

exec sp_executesql @sql