在 Gridview 中对大量数据进行分页

发布于 2024-07-27 17:13:00 字数 2183 浏览 5 评论 0原文

好的,请耐心等待,因为我有时会有点像木鸭……

我在 ASP.NET 中有一个网格视图,它将拉回数千条记录。 除了性能方面之外,这一切都很好。 我将 Gridview 绑定到数据集,这会拉回查询中的每条记录。 我想更改此设置,以便 gridview 只拉回当前显示的记录,然后当用户移动到下一页时,它会获取下一个数据块等。

下面是我通常如何绑定 gridview 和处理分页和排序,这对于小数据量来说非常有效,但对于大数据量则不太好。 我使用 SubSonic 作为我的 DAL,这很酷。 谁能指出我如何最好地实现上述分页的正确方向?

提前致谢...

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

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. 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. 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.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

墨小沫ゞ 2024-08-03 17:13:00

DbDataAdapter 类的 Fill() 方法为此目的提供了一个方便的重载:

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

在此重载中,您可以提供要开始的记录号以及要检索的最大记录数从那个起点开始。 这使您能够根据当前页面索引仅从数据源检索记录的子集。 您需要跟踪的只是显示的当前记录索引。

因此,您需要修改 DAL 来提供此重载。 我没有使用过 SubSonic,所以我无法判断它是否存在该功能。

The Fill() method of DbDataAdapter class has a convenient overload for this very purpose :

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. I haven't used SubSonic so I can't tell if that feature exists in it.

忆梦 2024-08-03 17:13:00

您使用什么版本的 ASP.NET?
.NET 3.5中ListView自带了一个DataPager控件
请参阅 system.web.ui.webcontrols.datapager

SubSonic 还支持分页,您应该在查询中内联调用 Paged 方法。 请参阅 SubSonic 寻呼

what version of ASP.NET do you use?
There is a DataPager control that comes with ListView in .NET 3.5
See system.web.ui.webcontrols.datapager

SubSonic also supports paging, you should call to the Paged method inline in the query. See SubSonic Paging

玻璃人 2024-08-03 17:13:00

您可以做的一件事是缓冲网络服务器中的数据并将数据页传输到网络浏览器。 您可以使用 GridView 控件并创建一个后台线程来实现此目的,该线程使用 SqlDataReader 从数据库中提取数据以填充缓冲区。 然后浏览器使用 AJAX 从网络服务器提取数据页(第一页、第二页等 200 行),直到缓冲区中的所有行都传输到浏览器并将其存储在 JavaScript 字符串数组中。

我发现这个策略很有效,并且经过最多 300,000 行 18 列的测试。 优点之一是数据分页不依赖于您的数据库。 您甚至可以对缓冲区(可以是数据表)执行排序,而不用再次访问数据库。

要了解更多信息,您可以点击此链接.希望这会有所帮助。

One thing you can do is to buffer the data in the webserver and stream your data-pages to the web-browser. 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. 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.

I find this strategy effective and tested to a maximum of 300,000 rows with 18 columns. 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.

To find out more, you can follow this link. Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文