简体   繁体   English

在Gridview中分页大量数据

[英]Paging large amounts of Data in a Gridview

Ok, please bear with me as I can be a bit of a wood duck at times... 好吧,请多多包涵,因为有时我可能有点像木头鸭...

I have a gridview in asp.net that will be pulling back many thousand of records. 我在asp.net中有一个gridview,它将撤回数千条记录。 This is all well and good apart from the performance aspect of things. 除了事物的性能方面,这一切都很好。 I am binding my Gridview to a dataset and this pulls back every record in the query. 我将Gridview绑定到数据集,这会拉回查询中的每条记录。 I want to change this so that the gridview only pulls back the records that it is currently displaying and then when the user moves to the next page it goes and gets the next chuck of data etc. 我想更改它,以便gridview只拉回它当前显示的记录,然后当用户移动到下一页时,它会获取下一个数据。

Below is how I normally bind my gridviews and handle the paging and sorting, which works very well for me with small data amounts, but not so good for large data amounts. 下面是我通常如何绑定网格视图并处理分页和排序的方式,这对于小数据量的我来说效果很好,但对大数据量的效果不好。 I use SubSonic as my DAL, which is cool. 我使用SubSonic作为我的DAL,这很酷。 Can anyone point me in the right direction on how best to achieve paging as described above? 有人能指出我关于如何最好地实现如上所述的分页的正确方向吗?

Thanks in advance... 提前致谢...

public SortDirection SortDir
{
    get
    {
        if (ViewState["sortDirection"] == null)
        {
            ViewState["sortDirection"] = SortDirection.Ascending;
        } return (SortDirection)ViewState["sortDirection"];
    }
    set
    {
        ViewState["sortDirection"] = value;
    }
}

DataSet ds = new DataSet();
DataView dv = new DataView();

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        BindGrid();
        GridView1.DataSource = dv;
        GridView1.DataBind();
    }
}

private DataView BindGrid()
{
    ds = new Query(AnthemWeb.DAL.Item.Schema).ExecuteDataSet();

    if (ViewState["sortExpr"] != null)
    {
        dv = new DataView(ds.Tables[0]);
        dv.Sort = (string)ViewState["sortExpr"];
    }
    else
    {
        dv = ds.Tables[0].DefaultView;
    }

    return dv;
}

protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    GridView1.PageIndex = e.NewPageIndex;
    GridView1.DataSource = BindGrid();
    GridView1.DataBind();
}

protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
    string stExp = e.SortExpression;
    string stDir = string.Empty;
    if (SortDir == SortDirection.Ascending)
    {
        SortDir = SortDirection.Descending;
        stDir = "DESC";
    }
    else
    {
        SortDir = SortDirection.Ascending;
        stDir = "ASC";
    }

    ViewState["sortExpr"] = e.SortExpression + " " + stDir;
    GridView1.DataSource = BindGrid();
    GridView1.DataBind();
}

protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
    int selectedRowIndex;
    selectedRowIndex = GridView1.SelectedIndex;
    GridViewRow row = GridView1.Rows[selectedRowIndex];
    string ID = row.Cells[0].Text;

    Response.Redirect("customer-details.aspx?ID=" + ID, false);
}

The Fill() method of DbDataAdapter class has a convenient overload for this very purpose : 为此, DbDataAdapter类的Fill()方法具有一个方便的重载:

public int Fill (DataSet dataSet, int startRecord, int maxRecords, string srcTable)

In this overload, you can provide the record number to start with and the maximum records to retrieve from that starting point. 在此重载中,您可以提供记录编号开头,并提供从该起始点检索的最大记录。 This enables you to retrieve only a subset of records from the datasource based on the current page index. 这使您可以基于当前页索引仅从数据源检索记录的一部分。 All you need to keep track of is the current record index that is displayed. 您需要跟踪的只是显示的当前记录索引。

So you would need to modify your DAL to provide this overload. 因此,您将需要修改DAL以提供此重载。 I haven't used SubSonic so I can't tell if that feature exists in it. 我没有使用SubSonic,所以我无法确定该功能是否存在。

what version of ASP.NET do you use? 您使用什么版本的ASP.NET? There is a DataPager control that comes with ListView in .NET 3.5 See system.web.ui.webcontrols.datapager .NET 3.5中的ListView附带有一个DataPager控件,请参见system.web.ui.webcontrols.datapager

SubSonic also supports paging, you should call to the Paged method inline in the query. SubSonic还支持分页,您应该在查询中内联调用Paged方法。 See SubSonic Paging 请参见SubSonic分页

One thing you can do is to buffer the data in the webserver and stream your data-pages to the web-browser. 您可以做的一件事是将数据缓存在Web服务器中,并将数据页面流式传输到Web浏览器。 You can acheive this using GridView conttrol and by creating a background thread that pulls data from your database to fill the buffer using SqlDataReader. 您可以使用GridView控制并通过创建一个后台线程来实现此目的,该线程从数据库中提取数据以使用SqlDataReader填充缓冲区。 Then browser pulls data-pages (200 rows of first page, seconds page and so on) from webserver using AJAX until all rows in the buffer is transmitted to the browser and store it in JavaScript string array. 然后,浏览器使用AJAX从Web服务器提取数据页(首页的200行,秒的页面等),直到缓冲区中的所有行都传输到浏览器并将其存储在JavaScript字符串数组中。

I find this strategy effective and tested to a maximum of 300,000 rows with 18 columns. 我发现此策略有效,并且最多测试了18列的300,000行。 One advantage is paging the data does not depends on your database. 优点之一是分页数据不依赖于数据库。 You can even perform sorting against the buffer (which can be a DataTable) instead of hitting the database again. 您甚至可以对缓冲区(可以是DataTable)执行排序,而不必再次访问数据库。

To find out more, you can follow this link. 要了解更多信息,您可以点击此链接。 Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM