再上数据分页控件(不用存储过程)

再上数据分页控件(不用存储过程)

发布日期:20110404日 星期一 作者:EricHu

本篇主要内容如下:

· 概述

· 本分页控件原理。

· 分页控件代码。

· 分页控件使用实例。

概述

在前几篇:我介绍了原创企业级控件库之大数据据量分页控件,这个控件主要是通过存储过程进行数据分页,得到了大家的支持,也给出了许多宝贵的建议,在这儿先感谢各位。同时也让我更有信心进行以后的文章(企业级控件库系列)。

分页对于每个项目来说都有它存在的意义,想起在以前刚刚刚软件开发时,由于刚刚毕业,理论知识雄厚,但实际工作经验欠缺,记得几年前做开发时,数据量很大,要用分页,一开始真不知道如何是好,方法到知道,但速度与稳定性却没有经验。在这儿,我只是起到一个抛砖引玉的作用,以便引起我们在实际工作中要多思考,对同一件事多想几种解决方式,只有这样才能不断提高,同时要学会总结。

这篇我将给大家介绍:不用存储过程,直接用代码来实现数据分页,欢迎大家拍砖,觉得不错的可以推荐下。同时,你要用什么好的想法,也可以与我交流,谢谢。

本分页控件原理

分页的方法很多,有用存储过程的,有不用存储过程的,还有在C#中用DataGridView的虚拟模式的,目的只有一个,对大数据量进行处理,让用户体验得到提高,软件速度得到提升。本分页控件主要是用了下面的SQL语句,我相信你能看懂的,存储过程分页也是用类似的SQL代码:

1/*TableName:表名如:tbTestData
2SqlWhereStatement :SqlWhere表达式如:where表达式为空
3PrimaryKey :主键如:UniqueID
4PageSize :分页大小如:50
5pageIndex:当前页如:8
6OrderField :排序字段如:InsetDataTime
7*/
8
9SELECTTOP50*FROMtbTestData
10WHEREUniqueIDNOTIN
11(
12SELECTTOP(50*8)UniqueIDFROMtbTestDataORDERBYInsetDataTimeDESC
13)
14ORDERBYInsetDataTimeDESC

原理就这么简单。

分页控件代码

(一)、实例数据库代码

创建实例数据库。

CREATETABLE[tbTestData](
[UniqueID][bigint]NOTNULL,
[CompanyName][varchar](200)NULL,
[CompanyCode][varchar](50)NULL,
[Address][varchar](500)NULL,
[Owner][varchar](100)NULL,
[Memo][varchar](2000)NULL,
[InsetDataTime][datetime]NULL,
CONSTRAINT[PK_tbTestData]PRIMARYKEYCLUSTERED
(
[UniqueID]ASC
)
WITH(PAD_INDEX=OFF,STATISTICS_NORECOMPUTE=OFF,IGNORE_DUP_KEY=OFF,ALLOW_ROW_LOCKS=ON,ALLOW_PAGE_LOCKS=ON)ON[PRIMARY]
)
ON[PRIMARY]

GO

ALTERTABLE[dbo].[tbTestData]ADDCONSTRAINT[DF_tbTestData_InsetDataTime]DEFAULT(getdate())FOR[InsetDataTime]
GO

--生成实例数据
declare@intRowNumberint;
select@intRowNumber=1;
while@intRowNumber<1000000
begin

insertintotbTestData(UniqueID,CompanyName,CompanyCode,Address,Owner,Memo)
values(@intRowNumber,'CompanyName'+cast(@intRowNumberasvarchar(2000)),
'CompanyCode'+cast(@intRowNumberasvarchar(2000)),'Address'+cast(@intRowNumberasvarchar(2000)),
'Owner'+cast(@intRowNumberasvarchar(2000)),'Memo'+cast(@intRowNumberasvarchar(2000)));
select@intRowNumber=@intRowNumber+1
end

(二)、分页控件代码。

namespaceDotNet.Controls
{
///<summary>
///分页控件(使用代码实现,不用存储过程)
///UcPageControlByCode
///修改纪录
///
///2010-01-06胡勇修改转到某页由原来的KeyPress方法改为KeyDown,让用户按回车键确认转页,以防止连续绑定两次。
///2011-01-06胡勇增加对分页控件的初始化代码:publicDataTableInitializePageControl()。
///2011-01-05胡勇创建分页控件
///2011-04-02胡勇优化代码、减少不必要的私有变量,去掉多余的代码
///
///<author>
///<name>胡勇</name>
///<QQ>80368704</QQ>
///<Email>[email protected]</Email>
///</author>
///</summary>
[ToolboxItem(true)]
[DefaultEvent(
"OnEventPageClicked")]
[ToolboxBitmap(
typeof(UcPageControlByCode),"Images.UcPageControlByCodeIcon.png")]
[Description(
"分页控件(使用代码实现,不用存储过程)")]
publicpartialclassUcPageControlByCode:UserControl
{
#region私有变量
intrecordCount=0;//记录数
intpageCount=0;//总页数
intpageIndex=0;//当前页
#endregion

#region自定义事件
///<summary>
///单击分页按钮(第一页、上一页、下一页、最后页、跳页)时发生
///</summary>
[Category("UcPageControlByCode"),Description("单击分页按钮时发生")]
publiceventEventHandlerOnEventPageClicked;
#endregion

#region自定义属性
privateint_pageSize=50;//分页大小
privatestring_sqlWhereStatement=string.Empty;//MsSqlWhere语句
privatestring_sqlConnString=string.Empty;//MsSql数据库连接字符串
privatestring_tableName=string.Empty;//表名
privatestring_orderField=string.Empty;//数据表的排序字段
privatestring_primaryKey=string.Empty;//数据表的主键
privatestring_queryFieldList="*";//字段列表(默认为:*)
privateDataTable_pageTable=newDataTable();

///<summary>
///返回当前页码
///</summary>
publicintPageIndex
{
get
{
returnpageIndex+1;
}
}

///<summary>
///得到或设置分页大小(默认为:50)
///</summary>
[Browsable(true),Category("UcPageControlByCode"),Description("得到或设置分页大小(默认为:50)")]
publicintPageSize
{
get
{
return_pageSize;
}
set
{
_pageSize
=value;
}
}

///<summary>
///SQL语句的Where表达式
///</summary>
[Browsable(false),Category("UcPageControlByCode"),Description("得到或设置SQL语句的Where表达式")]
publicstringSqlWhereStatement
{
get
{
return_sqlWhereStatement;
}
set
{
_sqlWhereStatement
=value;
}
}

///<summary>
///得到或设置SqlServer的连接字符串
///</summary>
[Browsable(false),Category("UcPageControlByCode"),Description("得到或设置SqlServer的连接字符串")]
publicstringSqlConnString
{
get
{
return_sqlConnString;
}
set
{
_sqlConnString
=value;
}
}

///<summary>
///得到用户单击分页按钮后返回的DataTable
///</summary>
[Browsable(false),Category("UcPageControlByCode"),Description("得到用户单击分页按钮后返回的DataTable")]
publicDataTablePageTable
{
get
{
return_pageTable;
}
}

///<summary>
///设置或得到与分页控件绑定的表名或视图名
///</summary>
[Browsable(true),Category("UcPageControlByCode"),Description("设置或得到与分页控件绑定的表名或视图名")]
publicstringTableName
{
get
{
return_tableName;
}
set
{
_tableName
=value;
}
}

///<summary>
///设置或得到分页控件排序字段
///</summary>
[Browsable(true),Category("UcPageControlByCode"),Description("设置或得到分页控件排序字段")]
publicstringOrderField
{
get
{
return_orderField;
}
set
{
_orderField
=value;
}
}

///<summary>
///设置或得到分页控件绑定数据表的主键
///</summary>
[Browsable(true),Category("UcPageControlByCode"),Description("设置或得到分页控件绑定数据表的主键")]
publicstringPrimaryKey
{
get
{
return_primaryKey;
}
set
{
_primaryKey
=value;
}
}

///<summary>
///设置或得到分页控件绑定的字段列表(默认为:*)
///</summary>
[Browsable(true),Category("UcPageControlByCode"),Description("设置或得到分页控件绑定的字段列表(默认为:*)")]
publicstringQueryFieldList
{
get
{
return_queryFieldList;
}
set
{
_queryFieldList
=value;
}
}
#endregion

#region构造函数
///<summary>
///分页控件(使用代码实现,不用存储过程)
///</summary>
publicUcPageControlByCode()
{
InitializeComponent();
}
#endregion

#region分页实现相关代码

#regionvoidSetUcPageControlPars(stringconnStr,stringwhereStatement,stringtbName,stringorderField,stringprimaryKeyName,stringfieldList):给UcPageControlByCode控件传递必需参数
///<summary>
///给UcPageControlByCode控件传递必需参数
///</summary>
///<paramname="connStr">连接字符串</param>
///<paramname="whereStatement">MsSqlWhere语句</param>
///<paramname="tbName">数据表名或视力名</param>
///<paramname="orderField">排序字段</param>
///<paramname="primaryKeyName">主键值</param>
///<paramname="fieldList">字段列表(默认为:*)</param>
publicvoidSetUcPageControlPars(stringconnStr,stringwhereStatement,stringtbName
,
stringorderField,stringprimaryKeyName,stringfieldList)
{
if(string.IsNullOrEmpty(connStr.Trim()))
{
DialogHelper.ShowErrorMsg(
"温馨提示:/n无可用的数据库连接!");
return;
}
else
{
this.SqlConnString=connStr;
}
this.SqlWhereStatement=whereStatement;
this.TableName=tbName;
this.OrderField=orderField;
this.PrimaryKey=primaryKeyName;
if(!string.IsNullOrEmpty(fieldList.Trim()))
{
this.QueryFieldList=fieldList;
}
}
#endregion

#regionDataTableInitializePageControl():初始化UcPageControlByCode
///<summary>
///绑定UcPageControlByCode(并返回包含当前页的DataTable)
///</summary>
///<returns>DataTable</returns>
publicDataTableBindPageControl()
{
recordCount
=GetTotalRecordCount();//获取总记录数
pageCount=recordCount/PageSize-ModPage();//保存总页数(减去ModPage()函数防止SQL语句执行时溢出查询范围,可以用存储过程分页算法来理解这句)
pageIndex=0;//保存一个为0的页面索引值到pageIndex
lblPageCount.Text=(recordCount/PageSize+OverPage()).ToString();//显示lblpageCount、lblrecCount的状态
lblRecCount.Text=recordCount.ToString();

if(recordCount<=PageSize)
{
txtGoToPage.Enabled
=false;
}
else
{
txtGoToPage.Enabled
=true;
}

returnTDataBind();
}
#endregion

#region余页计算与总记录数
///<summary>
///计算余页
///</summary>
///<returns></returns>
privateintOverPage()
{
intreturnValue=0;

if(recordCount%PageSize!=0)
{
returnValue
=1;
}

returnreturnValue;
}

///<summary>
///计算余页,防止SQL语句执行时溢出查询范围
///</summary>
///<returns></returns>
privateintModPage()
{
intreturnValue=0;

if(recordCount%PageSize==0&&recordCount!=0)
{
returnValue
=1;
}

returnreturnValue;
}

///<summary>
///计算总记录数
///</summary>
///<returns>记录总数</returns>
privateintGetTotalRecordCount()
{
intreturnValue=0;
stringsqlStatement="selectcount(1)asrowsCountfrom"+TableName;

if(SqlWhereStatement.Trim().Length>0)
{
sqlStatement
="selectcount(1)asrowsCountfrom"+TableName+"where"+SqlWhereStatement;
}

SqlDataReaderdr
=null;
try
{
dr
=DbHelperSQL.ExecuteReader(sqlStatement,SqlConnString);
if(dr.Read())
{
returnValue
=Int32.Parse(dr["rowsCount"].ToString());
}

}
catch(Exceptionex)
{
DialogHelper.ShowErrorMsg(ex.Message);
}
finally
{
dr.Close();
dr.Dispose();
}

returnreturnValue;
}
#endregion

#regionDataTableTDataBind():数据绑定
privateDataTableTDataBind()
{
StringBuildersbSqlStatement
=newStringBuilder();
boolisForward=pageIndex+1>1;
boolisBackward=(pageIndex!=pageCount);
btnFirstPage.Enabled
=isForward;
btnPrevPage.Enabled
=isForward;
btnNextPage.Enabled
=isBackward;
btnLastPage.Enabled
=isBackward;

if(string.IsNullOrEmpty(SqlWhereStatement.Trim()))
{
sbSqlStatement.Append(
"SELECTTOP"+PageSize+""+QueryFieldList+"FROM"+TableName+"WHERE"+PrimaryKey+"NOTIN(SELECTTOP");
sbSqlStatement.Append(PageSize
*pageIndex+""+PrimaryKey+"FROM"+TableName);
sbSqlStatement.Append(
"ORDERBY"+OrderField+"DESC)ORDERBY"+OrderField+"DESC");
}
else
{
sbSqlStatement.Append(
"SELECTTOP"+PageSize+""+QueryFieldList+"FROM"+TableName+"WHERE"+SqlWhereStatement+"AND"+PrimaryKey+"NOTIN(SELECTTOP");
sbSqlStatement.Append(PageSize
*pageIndex+""+PrimaryKey+"FROM"+TableName+"WHERE"+SqlWhereStatement+"ORDERBY"+OrderField+"DESC)ORDERBY"+OrderField+"DESC");
}

_pageTable
=DbHelperSQL.Query(sbSqlStatement.ToString(),SqlConnString).Tables[0];
lblCurrentPage.Text
=(pageIndex+1).ToString();
txtGoToPage.Text
=(pageIndex+1).ToString();
return_pageTable;
}
#endregion

#region按钮事件代码
privatevoidbtnFirstPage_Click(objectsender,EventArgse)
{
pageIndex
=0;
_pageTable
=TDataBind();

if(OnEventPageClicked!=null)
{
OnEventPageClicked(
this,null);
}
}

privatevoidbtnPrevPage_Click(objectsender,EventArgse)
{
pageIndex
--;
_pageTable
=TDataBind();

if(OnEventPageClicked!=null)
{
OnEventPageClicked(
this,null);
}
}

privatevoidbtnNextPage_Click(objectsender,EventArgse)
{
pageIndex
++;
_pageTable
=TDataBind();

if(OnEventPageClicked!=null)
{
OnEventPageClicked(
this,null);
}
}

privatevoidbtnLastPage_Click(objectsender,EventArgse)
{
pageIndex
=pageCount;
_pageTable
=TDataBind();

if(OnEventPageClicked!=null)
{
OnEventPageClicked(
this,null);
}
}

privatevoidtxtGoToPage_KeyDown(objectsender,KeyEventArgse)
{
if(e.KeyCode==Keys.Enter)
{
try
{
if(Int32.Parse(txtGoToPage.Text)>(recordCount/PageSize+OverPage())||Int32.Parse(txtGoToPage.Text)<=0)
{
DialogHelper.ShowWarningMsg(
"页码范围越界!");
txtGoToPage.Clear();
txtGoToPage.Focus();
}
else
{
pageIndex
=Int32.Parse(txtGoToPage.Text.ToString())-1;
_pageTable
=TDataBind();

if(OnEventPageClicked!=null)
{
OnEventPageClicked(
this,null);
}
}
}
catch(Exceptionex)//捕获由用户输入不正确数据类型时造成的异常
{
DialogHelper.ShowWarningMsg(ex.Message);
txtGoToPage.Clear();
txtGoToPage.Focus();
}
}
}
#endregion

#endregion
}
}

分页控件使用实例

客户端使用代码如下:

再上数据分页控件(不用存储过程)再上数据分页控件(不用存储过程)View Code
1usingSystem;
2usingSystem.Collections.Generic;
3usingSystem.ComponentModel;
4usingSystem.Data;
5usingSystem.Drawing;
6usingSystem.Configuration;
7usingDotNet.Controls;
8usingSystem.Text;
9usingSystem.Windows.Forms;
10usingDotNet.Common;
11usingDotNet.WinForm.Utilities;
12
13namespaceDotNet.WinForm.Example
14{
15publicpartialclassFrmUcPageControlByCodeTest:Form
16{
17publicFrmUcPageControlByCodeTest()
18{
19InitializeComponent();
20}
21
22privatevoidFrmUcPageControlByCodeTest_Shown(objectsender,EventArgse)
23{
24//初始化方法一
25//ucPageControlByCode.SqlConnString=ConfigurationSettings.AppSettings["DbConnection"];
26//ucPageControlByCode.SqlWhereStatement="1=1";
27//ucPageControlByCode.TableName="tbTestData";
28//ucPageControlByCode.OrderField="UniqueID";
29//ucPageControlByCode.PrimaryKey="UniqueID";
30//ucPageControlByCode.QueryFieldList="*";
31
32//初始化方法二
33ucPageControlByCode.SetUcPageControlPars(ConfigurationSettings.AppSettings["DbConnection"],"1=1","tbTestData",
34"UniqueID","UniqueID","*");
35DataTabledtTest=newDataTable();
36dtTest=ucPageControlByCode.BindPageControl();
37ucDataGridView.DataSource=dtTest;
38
39//绑定查询项
40Dictionary<string,string>dicListQueryItems=newDictionary<string,string>();
41foreach(DataColumndcindtTest.Columns)
42{
43dicListQueryItems.Add(dc.ColumnName,dc.DataType.ToString());
44}
45ucCombinQuery1.SetQueryItems(dicListQueryItems);
46}
47
48privatevoiducDataGridView_DataBindingComplete(objectsender,DataGridViewBindingCompleteEventArgse)
49{
50gbMain.Text="当前共:"+ucDataGridView.Rows.Count.ToString()+"条数据。";
51}
52
53privatevoiducPageControlByCode_OnEventPageClicked(objectsender,EventArgse)
54{
55ucDataGridView.DataSource=null;
56ucDataGridView.DataSource=ucPageControlByCode.PageTable;
57}
58
59privatevoiducCombinQuery1_OnQueryClicked(objectsender,EventArgse)
60{
61try
62{
63Splasher.Show(typeof(FrmSplash));
64Splasher.Status="正在查找数据,请稍等...";
65System.Threading.Thread.Sleep(450);
66ucDataGridView.DataSource=null;
67ucPageControlByCode.SqlWhereStatement=ucCombinQuery1.QueryExpression;//指定查询表达式
68ucDataGridView.DataSource=ucPageControlByCode.BindPageControl();//绑定DataGridView
69}
70catch(Exceptionex)
71{
72ucPageControlByCode.SqlWhereStatement="1<>1";
73ucDataGridView.DataSource=ucPageControlByCode.BindPageControl();//绑定DataGridView
74Splasher.Status=ex.Message;
75System.Threading.Thread.Sleep(1000);
76}
77finally
78{
79System.Threading.Thread.Sleep(100);
80Splasher.Status="查找完毕...";
81Splasher.Close();
82}
83}
84}
85}

最后的效果如下:

再上数据分页控件(不用存储过程)

© 2011 EricHu

原创作品,转贴请注明作者和出处,留此信息。

------------------------------------------------

cnBlobs:http://www.cnblogs.com/huyong/
****http://blog.****.net/chinahuyong

作者:EricHuDBC/SB/SWebServiceWCFPM等)
出处:http://www.cnblogs.com/huyong/

Q Q80368704 E-Mail: [email protected]
本博文欢迎大家浏览和转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,在『参考』的文章中,我会表明参考的文章来源,尊重他人版权。若您发现我侵犯了您的版权,请及时与我联系。
更多文章请看[置顶]索引贴——(不断更新中)