使用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 取得中间的一段数据就行了。用起来比原先的那个简单。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 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——大语言模型本地部署的极速利器