ASP.NET分页管理器的设计及实现

开发 后端
本文通过在DataGrid的web版控件中提供的自动分页的功能实现ASP.NET分页管理器,这款分页管理器支持随机跳转和缓存。

在DataGrid的web版控件中提供了自动分页的功能,但是我从来没用过它,因为它实现的分页只是一种假相。我们为什么需要分页?那是因为符合条件的记录可能很多,如果一次读取所有的记录,不仅延长获取数据的时间,而且也极度浪费内存。而分页的存在的主要目的正是为了解决这两个问题(当然,也不排除为了UI美观的需要而使用分页的)。而web版的DataGrid是怎样实现分页的了?它并没有打算解决上述两个问题,而还是一次读取所有的数据,然后以分页的样子表现出来。这是对效率和内存的极大损害!

于是我自己实现了ASP.NET分页管理器IPaginationManager ,IPaginationManager 每次从数据库中读取指定的任意一页,并且可以缓存指定数量的page。这个分页管理器的主要特点是:

(1)支持随机跳转。这是通过嵌套Select语句实现的。

(2)支持缓存。通过EnterpriseServerBase.DataStructure.FixCacher进行支持。

先来看看IPaginationManager接口的定义:

  1. public interface IPaginationManager  
  2. {  
  3. void Initialize(DataPaginationParas paras) ;  
  4. void Initialize(IDBAccesser accesser ,  
  5. int page_Size ,string whereStr ,string[]   
  6. fields) ;//如果选择所有列,fields可传null 
  7.  
  8. DataTable GetPage(int index) ; //取出第index页  
  9. DataTable CurrentPage() ;  
  10. DataTable PrePage() ;  
  11. DataTable NextPage() ;  
  12.  
  13. int PageCount{get ;}  
  14. int CacherSize{get; set; }  

这个接口定义中,最主要的是GetPage()方法,实现了这个方法,其它的三个获取页面的方法CurrentPage、PrePage、NextPage也就非常容易了。另外,CacherSize属性可以让我们指定缓存页面的数量。如果不需要缓存,则设置其值<=0,如果需要无限缓存,则值为Int.MaxValue。

IPaginationManager接口中的第二个Initialize方法,你不要关心,它是给XCodeFactory生成的数据层使用了,我们来看看第一个Initialize方法的参数类型DataPaginationParas的定义:

  1. public class DataPaginationParas  
  2. {  
  3. public int PageSize = 10 ;   
  4. public string[] Fields = {"*"};   
  5. //要搜索出的列,"*"表示所有列  
  6.  
  7. public string ConnectString ;  
  8. public string TableName ;   
  9. public string WhereStr ;   
  10. //搜索条件的where字句  
  11.  
  12. public DataPaginationParas  
  13. (string connStr ,string tableName ,  
  14. string whereStr)  
  15. {  
  16. this.ConnectString = connStr ;  
  17. this.TableName = tableName ;  
  18. this.WhereStr = whereStr ;  
  19. }   
  20.  
  21. #region GetFiedString  
  22. public string GetFiedString()  
  23. {  
  24. if(this.Fields == null)   
  25. {  
  26. this.Fields = new string[] {"*"} ;  
  27. }  
  28.  
  29. string fieldStrs = "" ;  
  30.  
  31. for(int i=0 ;i
  32. {  
  33. fieldStrs += " " + this.Fields[i] ;  
  34. if(i != (this.Fields.Length -1))  
  35. {  
  36. fieldStrs += " , " ;  
  37. }  
  38. else 
  39. {  
  40. fieldStrs += " " ;  
  41. }  
  42. }  
  43. return fieldStrs ;  
  44. }  
  45. #endregion  

DataPaginationParas.GetFiedString用于把要搜索的列形成字符串以便嵌入到SQL语句中。DataPaginationParas中的其它字段的意思都很明显。

现在来看看ASP.NET分页管理器的实现了:

  1. public class PaginationManager :IPaginationManager  
  2. {  
  3. private DataPaginationParas theParas ;  
  4. private IADOBase adoBase ;   
  5. private DataTable curPage = null ;  
  6. private int itemCount = 0 ;  
  7. private int pageCount = -1 ;   
  8. private int curPageIndex = -1 ;  
  9.  
  10. private FixCacher fixCacher = null ;  
  11. private string fieldStrs = "" ;  
  12.  
  13. ///   
  14. /// cacheSize 小于等于0 -- 表示不缓存 ,  
  15. Int.MaxValue -- 缓存所有  
  16. /// 
  17.    
  18. public PaginationManager(int cacheSize)  
  19. {  
  20. if(cacheSize == int.MaxValue)  
  21. {  
  22. this.fixCacher = new FixCacher() ;  
  23. }  
  24. else if(cacheSize >0)  
  25. {  
  26. this.fixCacher = new FixCacher(cacheSize) ;  
  27. }  
  28. else 
  29. {  
  30. this.fixCacher = null ;  
  31. }  
  32. }   
  33.  
  34. public PaginationManager()  
  35. {}  
  36.  
  37. #region IDataPaginationManager 成员  
  38. public int CacherSize  
  39. {  
  40. get  
  41. {  
  42. if(this.fixCacher == null)  
  43. {  
  44. return 0 ;  
  45. }  
  46. return this.fixCacher.Size ;  
  47. }  
  48. set 
  49. {  
  50. if(this.fixCacher == null)  
  51. {  
  52. this.fixCacher = new FixCacher(value) ;  
  53. }  
  54. else 
  55. {  
  56. this.fixCacher.Size = value ;  
  57. }  
  58. }  
  59. }  
  60. public int PageCount  
  61. {  
  62. get  
  63. {  
  64. if(this.pageCount == -1)  
  65. {  
  66. string selCountStr = string.Format  
  67. ("Select count(*) from {0} {1}" ,this.theParas.  
  68. TableName ,this.theParas.WhereStr) ;  
  69. DataSet ds = this.adoBase.DoQuery(selCountStr) ;  
  70. this.itemCount = int.Parse(ds.Tables[0].  
  71. Rows[0][0].ToString()) ;  
  72. this.pageCount = this.itemCount/this.  
  73. theParas.PageSize ;  
  74. if((this.itemCount%this.theParas.PageSize > 0))  
  75. {  
  76. ++ this.pageCount ;  
  77. }  
  78. }  
  79. return this.pageCount ;  
  80. }  
  81. }  
  82.  
  83. ///   
  84. /// GetPage 取出指定的一页  
  85. /// 
  86.    
  87. public DataTable GetPage(int index)  
  88. {  
  89. if(index == this.curPageIndex)  
  90. {  
  91. return this.curPage ;  
  92. }  
  93.  
  94. if((index < 0) || (index > (this.PageCount-1)))  
  95. {  
  96. return null;  
  97. }  
  98.  
  99. DataTable dt = this.GetCachedObject(index) ;  
  100.  
  101. if(dt == null)  
  102. {  
  103. string selectStr = this.ConstrutSelectStr(index) ;  
  104. DataSet ds = this.adoBase.DoQuery(selectStr) ;  
  105. dt = ds.Tables[0] ;  
  106.  
  107. this.CacheObject(index ,dt) ;  
  108. }  
  109. this.curPage = dt ;  
  110. this.curPageIndex = index ;  
  111. return this.curPage ;  
  112. }  
  113.  
  114. private DataTable GetCachedObject(int index)  
  115. {  
  116. if(this.fixCacher == null)  
  117. {  
  118. return null ;  
  119. }  
  120. return (DataTable)this.fixCacher[index] ;  
  121. }  
  122.  
  123. private void CacheObject(int index ,DataTable page)  
  124. {  
  125. if(this.fixCacher != null)  
  126. {  
  127. this.fixCacher.PutIn(index ,page) ;  
  128. }  
  129. }  
  130.  
  131. public DataTable CurrentPage()  
  132. {  
  133. return this.curPage ;  
  134. }  
  135.  
  136. public DataTable PrePage()  
  137. {  
  138. return this.GetPage((--this.curPageIndex)) ;  
  139. }  
  140.  
  141. public DataTable NextPage()  
  142. {  
  143. return this.GetPage((++this.curPageIndex)) ;  
  144. }   
  145.  
  146. private string ConstrutSelectStr(int pageIndex)  
  147. {  
  148. if(pageIndex == 0)  
  149. {  
  150. return string.Format("Select top {0} {1} from   
  151. {2} {3} ORDER BY ID" ,this.theParas.PageSize ,  
  152. this.fieldStrs ,this.theParas.TableName ,  
  153. this.theParas.WhereStr) ;  
  154. }  
  155.  
  156. int innerCount = this.itemCount -   
  157. this.theParas.PageSize*pageIndex ;  
  158. string innerSelStr = string.Format("Select   
  159. top {0} {1} from {2} {3} ORDER BY ID DESC " ,  
  160. innerCount , this.fieldStrs ,this.theParas.  
  161. TableName ,this.theParas.WhereStr) ;  
  162. string outerSelStr = string.Format("Select top {0}   
  163. from ({1}) DERIVEDTBL ORDER BY ID" ,this.  
  164. theParas.PageSize ,innerSelStr) ;  
  165.  
  166. return outerSelStr ;  
  167. }  
  168.  
  169. #region Initialize  
  170. public void Initialize(IDBAccesser accesser,   
  171. int page_Size, string whereStr, string[] fields)  
  172. {  
  173. this.theParas = new DataPaginationParas(accesser.  
  174. ConnectString ,accesser.DbTableName ,whereStr) ;  
  175. this.theParas.Fields = fields ;  
  176. this.theParas.PageSize = page_Size ;  
  177.  
  178. this.fieldStrs = this.theParas.GetFiedString() ;   
  179. this.adoBase = new SqlADOBase(this.theParas.  
  180. ConnectString) ;  
  181. }   
  182.  
  183. public void Initialize(DataPaginationParas paras)  
  184. {  
  185. this.theParas = paras ;  
  186. this.fieldStrs = this.theParas.GetFiedString() ;   
  187. this.adoBase = new SqlADOBase(this.theParas.  
  188. ConnectString) ;  
  189. }  
  190.  
  191. #endregion  
  192. #endregion  

解这个类的实现,可以从GetPage(int index)方法入手,另外私有方法ConstrutSelectStr()的实现说明了如何使用嵌套sql语句进行随机分页搜索。

最后,关于分页管理器,需要指出的是,搜索对应的表必须有一个名为"ID"的主键--这是唯一的要求。另外,分页管理器实现用到的数据访问低阶封装IADOBase定义于EnterpriseServerBase类库中。

使用ASP.NET分页管理器是很简单的,加上UI界面后,只要把返回的DataTable绑定到DataGrid就可以了。

【编辑推荐】

  1. ASP.NET特点概述(1)
  2. ASP.NET多语言支持组件简介
  3. ASP.NET服务器控件编程浅析
  4. ASP.NET移动开发入门基础(1)
  5. ASP.NET SqlDataSource控件入门
责任编辑:冰荷 来源: yesky
相关推荐

2009-08-05 13:50:23

ASP.NET状态管理

2009-08-14 13:37:25

ASP.NET静态页面

2009-07-28 14:47:18

ASP.NET MVC

2009-08-04 14:18:49

ASP.NET邮件列表

2009-11-06 09:23:41

ASP.NET高效分页

2009-09-10 09:50:47

ASP.NET MVC

2009-07-22 16:02:39

ASP.NET MVCPagedList

2012-04-23 15:10:18

ASP.NET

2009-08-04 14:23:36

ASP.NET查询分页

2009-08-12 14:10:37

asp.net分页代码

2009-08-12 18:19:46

ASP.NET报表打印

2009-08-07 17:49:44

控件设计器

2012-04-13 10:05:24

ASP.NET

2009-08-10 14:08:15

ASP.NET服务器控ASP.NET组件设计

2010-03-19 09:17:16

ASP.NET MVC

2009-08-05 16:59:55

ASP.NET组件设计

2009-08-10 13:32:15

ASP.NET TimASP.NET组件设计

2009-08-03 14:15:24

ASP.NET系统用户

2015-03-03 13:15:19

ASP.NET大文件下载实现思路

2009-08-05 16:53:14

ASP.NET组件设计
点赞
收藏

51CTO技术栈公众号