分享
 
 
 

利用ASP.NET实现分页管理器

王朝asp·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

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

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

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

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

先来看看IPaginationManager接口的定义:

public interface IPaginationManager

{

void Initialize(DataPaginationParas paras) ;

void Initialize(IDBAccesser accesser ,int page_Size ,string whereStr ,string[] fields) ;//如果选择所有列,

fields可传null

DataTable GetPage(int index) ; //取出第index页

DataTable CurrentPage() ;

DataTable PrePage() ;

DataTable NextPage() ;

int PageCount{get ;}

int CacherSize{get; set; }

}

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

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

public class DataPaginationParas

{

public int PageSize = 10 ;

public string[] Fields = {"*"}; //要搜索出的列,"*"表示所有列

public string ConnectString ;

public string TableName ;

public string WhereStr ; //搜索条件的where字句

public DataPaginationParas(string connStr ,string tableName ,string whereStr)

{

this.ConnectString = connStr ;

this.TableName = tableName ;

this.WhereStr = whereStr ;

}

#region GetFiedString

public string GetFiedString()

{

if(this.Fields == null)

{

this.Fields = newstring[] {"*"} ;

}

string fieldStrs = "" ;

for(int i=0 ;i

{

fieldStrs += " " + this.Fields[i] ;

if(i != (this.Fields.Length -1))

{

fieldStrs += " , " ;

}

else

{

fieldStrs += " " ;

}

}

return fieldStrs ;

}

#endregion

}

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

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

public class PaginationManager :IPaginationManager

{

private DataPaginationParas theParas ;

private IADOBase adoBase ;

private DataTable curPage = null ;

private int itemCount = 0 ;

private int pageCount = -1 ;

private int curPageIndex = -1 ;

private FixCacher fixCacher = null ;

private string fieldStrs = "" ;

///

/// cacheSize 小于等于0 -- 表示不缓存 ,Int.MaxValue -- 缓存所有

///

public PaginationManager(int cacheSize)

{

if(cacheSize == int.MaxValue)

{

this.fixCacher = new FixCacher() ;

}

else if(cacheSize >0)

{

this.fixCacher = new FixCacher(cacheSize) ;

}

else

{

this.fixCacher = null ;

}

}

public PaginationManager()

{}

#region IDataPaginationManager 成员

public int CacherSize

{

get

{

if(this.fixCacher == null)

{

return 0 ;

}

return this.fixCacher.Size ;

}

set

{

if(this.fixCacher == null)

{

this.fixCacher = new FixCacher(value) ;

}

else

{

this.fixCacher.Size = value ;

}

}

}

public int PageCount

{

get

{

if(this.pageCount == -1)

{

string selCountStr = string.Format("Select count(*) from {0} {1}" ,this.theParas.TableName ,this.theParas.WhereStr) ;

DataSet ds= this.adoBase.DoQuery(selCountStr) ;

this.itemCount = int.Parse(ds.Tables[0].Rows[0][0].ToString()) ;

this.pageCount = this.itemCount/this.theParas.PageSize ;

if((this.itemCount%this.theParas.PageSize >0))

{

++ this.pageCount ;

}

}

return this.pageCount ;

}

}

///

/// GetPage 取出指定的一页

///

public DataTable GetPage(int index)

{

if(index == this.curPageIndex)

{

return this.curPage ;

}

if((index < 0) || (index >(this.PageCount-1)))

{

return null;

}

DataTable dt = this.GetCachedObject(index) ;

if(dt == null)

{

string selectStr = this.ConstrutSelectStr(index) ;

DataSet ds = this.adoBase.DoQuery(selectStr) ;

dt = ds.Tables[0] ;

this.CacheObject(index ,dt) ;

}

this.curPage = dt ;

this.curPageIndex = index ;

return this.curPage ;

}

private DataTable GetCachedObject(int index)

{

if(this.fixCacher == null)

{

return null ;

}

return (DataTable)this.fixCacher[index] ;

}

private void CacheObject(int index ,DataTable page)

{

if(this.fixCacher != null)

{

this.fixCacher.PutIn(index ,page) ;

}

}

public DataTable CurrentPage()

{

return this.curPage ;

}

public DataTable PrePage()

{

return this.GetPage((--this.curPageIndex)) ;

}

public DataTable NextPage()

{

return this.GetPage((++this.curPageIndex)) ;

}

private string ConstrutSelectStr(int pageIndex)

{

if(pageIndex == 0)

{

return string.Format("Select top {0} {1} from {2} {3} ORDER BY ID" ,this.theParas.PageSize ,this.fieldStrs ,this.theParas.TableName ,this.theParas.WhereStr) ;

}

int innerCount = this.itemCount - this.theParas.PageSize*pageIndex ;

string innerSelStr = string.Format("Select top {0} {1} from {2} {3} ORDER BY ID DESC " ,innerCount , this.fieldStrs ,this.theParas.TableName ,this.theParas.WhereStr) ;

string outerSelStr = string.Format("Select top {0} * from ({1}) DERIVEDTBL ORDER BY ID" ,this.theParas.PageSize ,innerSelStr) ;

return outerSelStr ;

}

#region Initialize

public void Initialize(IDBAccesser accesser, int page_Size, string whereStr, string[] fields)

{

this.theParas = new DataPaginationParas(accesser.ConnectString ,accesser.DbTableName ,whereStr) ;

this.theParas.Fields = fields ;

this.theParas.PageSize = page_Size ;

this.fieldStrs = this.theParas.GetFiedString() ;

this.adoBase = new SqlADOBase(this.theParas.ConnectString) ;

}

public void Initialize(DataPaginationParas paras)

{

this.theParas = paras ;

this.fieldStrs = this.theParas.GetFiedString() ;

this.adoBase = new SqlADOBase(this.theParas.ConnectString) ;

}

#endregion

#endregion

}

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

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

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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有