C# 使用Repeater和SQL定制分页

C# 使用Repeater和SQL定制分页,c#,asp.net,sql,performance,optimization,C#,Asp.net,Sql,Performance,Optimization,我一直在寻找一个好的教程,教我如何使用一个简单的数据绑定控件(如Repeater)来定制分页控件,以实现高性能分页功能 我找到了很多关于这个问题的文章,但没有一篇是完整的答案 这是一个非常棒的例子,它提供了统计数据,并对不同的方法进行了很好的比较,但问题是在SQL Server使用新函数ROW_NUMBER()之前,它已经太旧了 这一个几乎是完美的,但他使用了网格现有的分页功能和定制的分页方法,而不是中继器 我认为这件事太复杂了,事情可以做得更容易 我正在使用SQL、Items Rep

我一直在寻找一个好的教程,教我如何使用一个简单的数据绑定控件(如Repeater)来定制分页控件,以实现高性能分页功能

我找到了很多关于这个问题的文章,但没有一篇是完整的答案

  • 这是一个非常棒的例子,它提供了统计数据,并对不同的方法进行了很好的比较,但问题是在SQL Server使用新函数ROW_NUMBER()之前,它已经太旧了

  • 这一个几乎是完美的,但他使用了网格现有的分页功能和定制的分页方法,而不是中继器

  • 我认为这件事太复杂了,事情可以做得更容易

我正在使用SQL、Items Repeater(在代码隐藏中直接绑定,不使用任何数据源)、PageNumbers Repeater(它将有一个链接作为ItemTemplate来传递querystring,以便使用的方法可以检索项的下一部分)、一个标签来保存当前页码和标题

我一直在尝试在上实现这个示例。到目前为止,我已经在数据访问工具中创建了一个SQL命令,如下所示:

WITH Records AS ( SELECT ItemId, ItemName, ROW_NUMBER() OVER (ORDER BY ItemId) AS 'RowNumber' FROM   Items)  SELECT * FROM Records WHERE (RowNumber BETWEEN (@startIndex) AND @startIndex + @pageSize - 1)

但现在我被困在如何在我的演示层中使用它

您可以创建自定义方法来呈现自己的分页控件。以下是一个例子:

    /// <summary>
    /// Produces html for a pagination control.
    /// </summary>
    /// <param name="page">Page number for the current page (1-based index).</param>
    /// <param name="pageSize">Number or items per page.</param>
    /// <param name="totalItems">Total number of items across all pages.</param>
    /// <returns>Html of a pagination control.</returns>
    public string RenderPaginationControl(int page, int pageSize, int totalItems)
    {
        int totalPages = (int)Math.Ceiling((double)totalItems/pageSize);

        // Create pager.
        StringBuilder pagerSb = new StringBuilder();
        for (int i = 1; i <= totalPages; ++i)
        {
            // If it is NOT a link to current page.
            if (i != page) { pagerSb.Append(string.Format("<a href='/data.aspx?page={0}'>{0}</a>", i)); }
            // If it is the link to current page.
            else { pagerSb.Append(string.Format("<span>{0}</span>", i)); }
        }

        return pagerSb.ToString();
    }
并将该值传递给RenderPaginationControl中的totalItems

就与Repeater的绑定而言,这非常简单:

this.MyRepeater.DataSource = DAL.GetItems(page, pageSize);
this.MyRepeater.DataBind();

int totalItems = DAL.GetTotalNumberOfItems();
this.PaginationLabel.Text = RenderPaginationControl(page, pageSize, totalItems);

看看您的上一个示例,您在实现它时面临哪些问题?它需要一个id、startindex和pagesize的方法。在我过去的4份工作中,我必须教人们如何使用中继器,没有关于使用中继器的好文章,我想我会把它作为我的下一篇博文。@gbs-让我浏览页面的中继器是我的问题。确切地说,我不知道应该给startIndex参数分配什么值,以及如何分配!菲尔-那太好了!我希望很快会有时间,完成后请与我们分享。@lKashef-我要到2月初才能完成,因为有一个项目的截止日期是2月1日。完成后,我将在此处发布一条带有链接的注释。@niaher-GetItems方法的代码中有一个小错误。保存startPageIndex不需要参数…我不知道如何向您说明,但缺少的是一个变量,它将是我的sql查询的新偏移量(@startIndex),用于为另一个给定的sql查询选择项目的新部分page@niaher-我通过向url添加一个“start”QueryString参数并添加一个变量“startIndex”解决了这个问题将它添加到方法中,并将其增加pageSize(startIndex+=pageSize)…但我想知道作为分页导航器的(StringBuilder+标签)是否比中继器更好。最后一个问题!我想使用Ajax,锚不允许我这么做,所以我需要使用服务器控件,比如LinkButton,来引起回发,让我的Ajax工作!有什么想法吗?…标记为answer btw,Thank you=我真的不明白为什么在GetItems方法中需要“startIndex”参数。您已经知道将来从每个链接中的“page”参数请求时需要哪个页面,例如-data.aspx?page=2。至于使用AJAX,我不确定,但您可以尝试使用一个页面并向其中添加控件,例如-MyPlaceHolder.controls.add(newlinkbutton(?))。@niaher-“WHERE(RowNumber-BETWEEN(@startIndex)和@startIndex+@pageSize-1)“查询需要知道给定页面的起始位置。例如,如果页面大小为4,则第一页的起始值为1,第二页的起始值为5,第三页的起始值为9,以此类推
this.MyRepeater.DataSource = DAL.GetItems(page, pageSize);
this.MyRepeater.DataBind();

int totalItems = DAL.GetTotalNumberOfItems();
this.PaginationLabel.Text = RenderPaginationControl(page, pageSize, totalItems);