再上数据分页控件(不用存储过程)
发布日期:2011年04月04日 星期一 作者:EricHu
本篇主要内容如下:
· 概述
· 本分页控件原理。
· 分页控件代码。
· 分页控件使用实例。
概述
在前几篇:我介绍了原创企业级控件库之大数据据量分页控件,这个控件主要是通过存储过程进行数据分页,得到了大家的支持,也给出了许多宝贵的建议,在这儿先感谢各位。同时也让我更有信心进行以后的文章(企业级控件库系列)。
分页对于每个项目来说都有它存在的意义,想起在以前刚刚刚软件开发时,由于刚刚毕业,理论知识雄厚,但实际工作经验欠缺,记得几年前做开发时,数据量很大,要用分页,一开始真不知道如何是好,方法到知道,但速度与稳定性却没有经验。在这儿,我只是起到一个抛砖引玉的作用,以便引起我们在实际工作中要多思考,对同一件事多想几种解决方式,只有这样才能不断提高,同时要学会总结。
这篇我将给大家介绍:不用存储过程,直接用代码来实现数据分页,欢迎大家拍砖,觉得不错的可以推荐下。同时,你要用什么好的想法,也可以与我交流,谢谢。
本分页控件原理
分页的方法很多,有用存储过程的,有不用存储过程的,还有在C#中用DataGridView的虚拟模式的,目的只有一个,对大数据量进行处理,让用户体验得到提高,软件速度得到提升。本分页控件主要是用了下面的SQL语句,我相信你能看懂的,存储过程分页也是用类似的SQL代码:
2 SqlWhereStatement :SqlWhere表达式如:where表达式为空
3 PrimaryKey :主键如:UniqueID
4 PageSize :分页大小如:50
5 pageIndex:当前页如:8
6 OrderField :排序字段如:InsetDataTime
7 */
8
9 SELECT TOP 50 * FROM tbTestData
10 WHERE UniqueID NOT IN
11 (
12 SELECT TOP ( 50 * 8 )UniqueID FROM tbTestData ORDER BY InsetDataTime DESC
13 )
14 ORDER BY InsetDataTime DESC
原理就这么简单。
分页控件代码
(一)、实例数据库代码
创建实例数据库。
[ UniqueID ] [ bigint ] NOT NULL ,
[ 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 ] PRIMARY KEY CLUSTERED
(
[ 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
ALTER TABLE [ dbo ] . [ tbTestData ] ADD CONSTRAINT [ DF_tbTestData_InsetDataTime ] DEFAULT ( getdate ()) FOR [ InsetDataTime ]
GO
--生成实例数据
declare @intRowNumber int ;
select @intRowNumber = 1 ;
while @intRowNumber < 1000000
begin
insert into tbTestData(UniqueID,CompanyName,CompanyCode,Address,Owner,Memo)
values ( @intRowNumber , ' CompanyName ' + cast ( @intRowNumber as varchar ( 2000 )),
' CompanyCode ' + cast ( @intRowNumber as varchar ( 2000 )), ' Address ' + cast ( @intRowNumber as varchar ( 2000 )),
' Owner ' + cast ( @intRowNumber as varchar ( 2000 )), ' Memo ' + cast ( @intRowNumber as varchar ( 2000 )));
select @intRowNumber = @intRowNumber + 1
end
(二)、分页控件代码。
{
/// <summary>
/// 分页控件(使用代码实现,不用存储过程)
/// UcPageControlByCode
/// 修改纪录
///
/// 2010-01-06胡勇修改转到某页由原来的KeyPress方法改为KeyDown,让用户按回车键确认转页,以防止连续绑定两次。
/// 2011-01-06胡勇增加对分页控件的初始化代码:publicDataTableInitializePageControl()。
/// 2011-01-05胡勇创建分页控件
/// 2011-04-02胡勇优化代码、减少不必要的私有变量,去掉多余的代码
///
/// <author>
/// <name> 胡勇 </name>
/// <QQ> 80368704 </QQ>
/// <Email> 80368704@qq.com </Email>
/// </author>
/// </summary>
[ToolboxItem( true )]
[DefaultEvent( " OnEventPageClicked " )]
[ToolboxBitmap( typeof (UcPageControlByCode), " Images.UcPageControlByCodeIcon.png " )]
[Description( " 分页控件(使用代码实现,不用存储过程) " )]
public partial class UcPageControlByCode:UserControl
{
#region 私有变量
int recordCount = 0 ; // 记录数
int pageCount = 0 ; // 总页数
int pageIndex = 0 ; // 当前页
#endregion
#region 自定义事件
/// <summary>
/// 单击分页按钮(第一页、上一页、下一页、最后页、跳页)时发生
/// </summary>
[Category( " UcPageControlByCode " ),Description( " 单击分页按钮时发生 " )]
public event EventHandlerOnEventPageClicked;
#endregion
#region 自定义属性
private int _pageSize = 50 ; // 分页大小
private string _sqlWhereStatement = string .Empty; // MsSqlWhere语句
private string _sqlConnString = string .Empty; // MsSql数据库连接字符串
private string _tableName = string .Empty; // 表名
private string _orderField = string .Empty; // 数据表的排序字段
private string _primaryKey = string .Empty; // 数据表的主键
private string _queryFieldList = " * " ; // 字段列表(默认为:*)
private DataTable_pageTable = new DataTable();
/// <summary>
/// 返回当前页码
/// </summary>
public int PageIndex
{
get
{
return pageIndex + 1 ;
}
}
/// <summary>
/// 得到或设置分页大小(默认为:50)
/// </summary>
[Browsable( true ),Category( " UcPageControlByCode " ),Description( " 得到或设置分页大小(默认为:50) " )]
public int PageSize
{
get
{
return _pageSize;
}
set
{
_pageSize = value;
}
}
/// <summary>
/// SQL语句的Where表达式
/// </summary>
[Browsable( false ),Category( " UcPageControlByCode " ),Description( " 得到或设置SQL语句的Where表达式 " )]
public string SqlWhereStatement
{
get
{
return _sqlWhereStatement;
}
set
{
_sqlWhereStatement = value;
}
}
/// <summary>
/// 得到或设置SqlServer的连接字符串
/// </summary>
[Browsable( false ),Category( " UcPageControlByCode " ),Description( " 得到或设置SqlServer的连接字符串 " )]
public string SqlConnString
{
get
{
return _sqlConnString;
}
set
{
_sqlConnString = value;
}
}
/// <summary>
/// 得到用户单击分页按钮后返回的DataTable
/// </summary>
[Browsable( false ),Category( " UcPageControlByCode " ),Description( " 得到用户单击分页按钮后返回的DataTable " )]
public DataTablePageTable
{
get
{
return _pageTable;
}
}
/// <summary>
/// 设置或得到与分页控件绑定的表名或视图名
/// </summary>
[Browsable( true ),Category( " UcPageControlByCode " ),Description( " 设置或得到与分页控件绑定的表名或视图名 " )]
public string TableName
{
get
{
return _tableName;
}
set
{
_tableName = value;
}
}
/// <summary>
/// 设置或得到分页控件排序字段
/// </summary>
[Browsable( true ),Category( " UcPageControlByCode " ),Description( " 设置或得到分页控件排序字段 " )]
public string OrderField
{
get
{
return _orderField;
}
set
{
_orderField = value;
}
}
/// <summary>
/// 设置或得到分页控件绑定数据表的主键
/// </summary>
[Browsable( true ),Category( " UcPageControlByCode " ),Description( " 设置或得到分页控件绑定数据表的主键 " )]
public string PrimaryKey
{
get
{
return _primaryKey;
}
set
{
_primaryKey = value;
}
}
/// <summary>
/// 设置或得到分页控件绑定的字段列表(默认为:*)
/// </summary>
[Browsable( true ),Category( " UcPageControlByCode " ),Description( " 设置或得到分页控件绑定的字段列表(默认为:*) " )]
public string QueryFieldList
{
get
{
return _queryFieldList;
}
set
{
_queryFieldList = value;
}
}
#endregion
#region 构造函数
/// <summary>
/// 分页控件(使用代码实现,不用存储过程)
/// </summary>
public UcPageControlByCode()
{
InitializeComponent();
}
#endregion
#region 分页实现相关代码
#region voidSetUcPageControlPars(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>
public void SetUcPageControlPars( string connStr, string whereStatement, string tbName
, string orderField, string primaryKeyName, string fieldList)
{
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
#region DataTableInitializePageControl():初始化UcPageControlByCode
/// <summary>
/// 绑定UcPageControlByCode(并返回包含当前页的DataTable)
/// </summary>
/// <returns> DataTable </returns>
public DataTableBindPageControl()
{
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 ;
}
return TDataBind();
}
#endregion
/// <summary>
/// 计算余页
/// </summary>
/// <returns></returns>
private int OverPage()
{
int returnValue = 0 ;
if (recordCount % PageSize != 0 )
{
returnValue = 1 ;
}
return returnValue;
}
/// <summary>
/// 计算余页,防止SQL语句执行时溢出查询范围
/// </summary>
/// <returns></returns>
private int ModPage()
{
int returnValue = 0 ;
if (recordCount % PageSize == 0 && recordCount != 0 )
{
returnValue = 1 ;
}
return returnValue;
}
/// <summary>
/// 计算总记录数
/// </summary>
/// <returns> 记录总数 </returns>
private int GetTotalRecordCount()
{
int returnValue = 0 ;
string sqlStatement = " 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();
}
return returnValue;
}
#endregion
#region DataTableTDataBind():数据绑定
private DataTableTDataBind()
{
StringBuildersbSqlStatement = new StringBuilder();
bool isForward = pageIndex + 1 > 1 ;
bool isBackward = (pageIndex != pageCount);
btnFirstPage.Enabled = isForward;
btnPrevPage.Enabled =