使用AspNetPager进行存储过程分页

         首先到这里下载最新的AspNetPager分页控件。

         因为是使用存储过程进行分页,所以效率就比使用GridView要高一些。因为他不是一下子将所有的数据全部读到内存,而是按需使用,用多少就拿多少。先来看一下存储过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
-- 分页存储过程
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:        钱李峰
-- Create date: 2011/3/30
-- =============================================
create PROCEDURE PagePro
@table varchar(100),    --需要分页的表
@pageIndex int = 1,        --查询页
@pageSize int = 5,        --每页显示个数
@conditionStr varchar(500) = '1=1',        --约束条件(不用加where)
@orderProperty varchar(500),        --排序依据的字段名(int类型)
@totalcount int = 0 output    --查询总数(需要传出)
 
AS
--下面是临时变量
declare @sql1 varchar(1000)
declare @sql2 varchar(1000)
declare @sql3 nvarchar(4000)
declare @sql varchar(1000)
declare @firstCount int
declare @start int
declare @end int
 
BEGIN
    --数据库通用查询方法
    --比如说我要查第2页,每页5条,既需要查6-10条。
    --可以先将第一页最大的记录ID找出来,然后找大于这个记录ID的5条记录就是了。
 
    --这个存储过程需要一个自增的字段(int类型)
 
--算出总共有多少条记录
        set @sql3 = 'select @totalcount = count(*) from '+@table +' where '+@conditionStr
        execute sp_executesql @sql3,N'@totalcount int output',@totalcount output
    print @totalcount
 
if @pageIndex = 1
    set @sql = 'select top '+str(@pageSize)+' * from '+@table +' where '+@conditionStr
else
    begin
        --获得n-1页得总个数
        set @firstCount = (@pageIndex - 1) * @pageSize
        --获得n-1页所有的记录
        set @sql1 = 'select top '+str(@firstCount)+' * from '+@table+' where '+@conditionStr +' order by '+ @orderProperty
        --将n-1页记录中的最大ID取出(所以此存储过程要求一个自增长的字段)
        set @sql2 = 'select max('+@orderProperty+') from ('+ @sql1+') as temp'
        --只要id大于前面选取的这个最大页,并且选取pageSize条记录,即为要查询的结果
        set @sql = 'select top '+str(@pageSize)+' * from '+@table+' where '+@orderProperty +' > ( '+@sql2+' ) and '+ @conditionStr
    end
 
print(@sql)
execute(@sql)
END
GO
 
--exec PagePro 't_feeling',3,15,'1=1','id',0

在程序中调用方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public static DataTable Pager(string tablename, string orderkey, string conditionStr, int pageIndex, int pageSize,
                      out int count)
{
    DataTable dt = new DataTable();
    //构造存储过程page的参数
    count = 0;
    SqlParameter[] paras = new SqlParameter[]{
           new SqlParameter("@table",tablename),
           new SqlParameter("@pageIndex",pageIndex),
           new SqlParameter("@pageSize",pageSize),
           new SqlParameter("@conditionStr",conditionStr),
           new SqlParameter("@orderProperty",orderkey),
           new SqlParameter("@totalcount",count),
        };
    paras[5].Direction = ParameterDirection.Output;   //指定count为输出类型
 
    string connstr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;  //连接字符串,需要在数据库中配置
    SqlConnection conn = new SqlConnection(connstr);
    conn.Open();
 
    SqlCommand cmd = new SqlCommand("PagePro", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.AddRange(paras);
 
    SqlDataReader sdr;
    using (sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
    {
        dt.Load(sdr);
    }
    count = Convert.ToInt32(paras[5].Value);
 
    return dt;
}

这样就能调用这个存储过程了。完成以上步骤分页也就完成了一半了,下面使用AspNetPager进行分页显示,在页面中加入AspNetPager,并进行如下样式设置(当然不设置也行)

1
2
3
4
5
6
7
8
9
10
<webdiyer:AspNetPager ID="AspNetPager1" runat="server"
    CurrentPageButtonClass="current" CurrentPageButtonPosition="Center"
    CurrentPageButtonStyle="font-color:blue"
    CustomInfoHTML="每页%PageSize%条记录 总共%RecordCount%条记录 页码:%CurrentPageIndex%/%PageCount%"
    FirstPageText="首页" LastPageText="尾页" NextPageText="下一页" NumericButtonCount="8"
    onpagechanging="AspNetPager1_PageChanging" PageIndexBoxType="TextBox"
    PrevPageText="上一页" ShowCustomInfoSection="Left" ShowMoreButtons="False"
    ShowPageIndex="False" ShowPageIndexBox="Always" SubmitButtonText="跳转"
    TextAfterPageIndexBox="页" TextBeforePageIndexBox="">
</webdiyer:AspNetPager>

注意,其中的onpagechanging="AspNetPager1_PageChanging"事件一定要写,否则就不能进行分页了。后台的AspNetPager1_PageChanging代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
protected void AspNetPager1_PageChanging(object src, Wuqi.Webdiyer.PageChangingEventArgs e)
{
    AspNetPager1.CurrentPageIndex = e.NewPageIndex;   //设置当前的页码
    GetPage();  //重新分页
}
 
private void GetPage()
{
    int count;
    Repeater1.DataSource = Pager("t_feeling", "id", "1=1", AspNetPager1.CurrentPageIndex, AspNetPager1.PageSize, out count);
    Repeater1.DataBind();
    AspNetPager1.RecordCount = count;  //这个也是必须的
}

这样这个简单的分页功能就好了,另外可能默认的分页样式不好看,你可以自己添加样式进行修改。

2011-4-6修改

上面用到的那个存储过程还存在一些局限性。比如,不能很好的支持按字段排序的功能,而且如果有的数据库没有自增字段的ID(用GUID代替了)那么这个存储过程执行起来也是有一定的问题的。下面提供一种基于SQL SERVER 2005的ROW_NUMBER()进行分页的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:        <Author,,Name>
-- Create date: <Create Date,,>
-- Description:    <Description,,>
-- =============================================
ALTER PROCEDURE [dbo].[PagePro]
@table varchar(100),  --要分页的表
@strcondition varchar(500),  --约束条件
@orderkey varchar(20), --排序的依据字段
@strorder varchar(4),   --排序的类型,desc是倒序,asc是正序)
@pageindex int=1,      --查询页
@pagesize  int=10,      --每页显示数目   
@totalcount int=0 output     --查询总数
AS
SET NOCOUNT ON
declare @SQL varchar(1000)      --执行分页语句1
declare @SQL1 varchar(1000)     --执行分页语句2
declare @SQLCount nvarchar(4000) --查询总数语句
declare @start as int              --查询开始位置
declare @end as int                --查询结束位置
BEGIN
 
--查询总数
set @SQLCount ='select @totalcount=count(*) from (select *,ROW_NUMBER() OVER(order by ' + @orderkey+' '+ @strorder+') as tempId  from '+@table+') as tmp
where '+@strcondition
execute sp_executesql @SQLCount,N'@totalcount int output',@totalcount output
 
--找到查询的开始位置
set @start=(@pageindex-1) * @pagesize + 1
 
--找到查询的结束位置
set @end=@pageindex * @pagesize
 
--,ROW_NUMBER() OVER(order by ' + @orderkey+' '+ @strorder+') as tempId
--执行分页
set @SQL ='select *,ROW_NUMBER() OVER(order by ' + @orderkey+' '+ @strorder+') as tempId from '+@table+'  where ' +@strcondition
 
set @SQL1 ='select * from ('+@SQL+') as temp2 where tempId between '+Convert(nvarchar,@start)+' and '+Convert (nvarchar,@end)
execute(@SQL1)
print @SQL1
END

利用ROW_NUMBER()这个方法,SQL SERVER会自动帮我们创建一个递增的序列号,这样我们分页的时候只要根据这个序列利用 between and 取得中间的一段数据就行了。用起来比原先的那个简单。

posted @   qianlifeng  阅读(3984)  评论(9编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
点击右上角即可分享
微信分享提示