最近给分页快搞死, 记得之前曾经发过修改 DW ASP 分页的方法, 后来又写过手工打造的 ASP 分页, 现在进入.NET 当然要配合存储过程打造纯手工高性能分页了. 为什么会叫做高性能, 为什么要手工打造, 不使用.NET 现有的分页控件呢? 这个还要追溯到我修改 DW ASP 分页的时候, 那个我还不怎么懂程序这个东西, 只会修修补补, 就更不要去谈什么性能问题. 当时改的很心烦, 接着叫我的私人技术总监张总帮我看看, 当时 张总就以一种不屑一顾的眼神往着我, 说了句话: 值得吗?
接着到我手工打造 ASP 分页, 又搞不下去了, 张总丢给我一堆.NET 的代码: 自己研究吧. 然后又丢了一句话: 用.NET 做吧, 几句话搞定, 不用这个费神.
后来我发现以前的分页都是把整个数据集全部读取后再做分页处理的, 一旦数据量过大, 处理会十分缓慢, 甚至服务器崩溃. 然后就是以前的分页不能象游标一样滚动, 总是固定在一组里面, 不可能实现当前页码在中间的效果.
接着就要说.NET 的分页控件了, 确实几句话可以搞定, 不过缺陷就是我发现的第一个问题, 属于把数据全部读出再处理的那种, 没有效率, 所以终于开始动手, 纯手工打造 ASP.NET 高性能分页.
首先是存储过程, 只取出我需要的那段数据, 如果页数超过数据总数, 自动返回最后一页的纪录:
复制代码 代码如下:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
– =============================================
– Author: Clear
– Create date: 2007-01-30
– Description: 高性能分页
– =============================================
Alter PROCEDURE [dbo].[Tag_Page_Name_Select]
– 传入最大显示纪录数和当前页码
@MaxPageSize int,
@PageNum int,
– 设置一个输出参数返回总纪录数供分页列表使用
@Count int output
AS
BEGIN
SET NOCOUNT ON;
DECLARE
– 定义排序名称参数
@Name nvarchar(50),
– 定义游标位置
@Cursor int
– 首先得到纪录总数
Select @Count = count(tag_Name)
FROM [viewdatabase0716].[dbo].[view_tag];
– 定义游标需要开始的位置
Set @Cursor = @MaxPageSize*(@PageNum-1)+1
– 如果游标大于纪录总数将游标放到最后一页开始的位置
IF @Cursor > @Count
BEGIN
– 如果最后一页与最大每次纪录数相等,返回最后整页
IF @Count % @MaxPageSize = 0
Set @Cursor = @Count – @MaxPageSize + 1
– 否则返回最后一页剩下的纪录
ELSE
Set @Cursor = @Count – (@Count % @MaxPageSize) + 1
END
– 将指针指到该页开始
Set Rowcount @Cursor
– 得到纪录开始的位置
Select @Name = tag_Name
FROM [viewdatabase0716].[dbo].[view_tag]
orDER BY tag_Name;
– 设置开始位置
Set Rowcount @MaxPageSize
– 得到该页纪录
Select *
From [viewdatabase0716].[dbo].[view_tag]
Where tag_Name >= @Name
order By tag_Name
Set Rowcount 0
END
然后是分页控件 (… 为省略的生成 HTML 代码方法):
复制代码 代码如下:
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
/// <summary>
/// 扩展连接字符串
/// </summary>
public class ExStringBuilder
{
private StringBuilder InsertString;
private StringBuilder PageString;
private int PrivatePageNum = 1;
private int PrivateMaxPageSize = 25;
private int PrivateMaxPages = 10;
private int PrivateCount;
private int PrivateAllPage;
public ExStringBuilder()
{
InsertString = new StringBuilder("");
}
/// <summary>
/// 得到生成的 HTML
/// </summary>
public string GetHtml
{
get
{
return InsertString.ToString();
}
}
/// <summary>
/// 得到生成的分页 HTML
/// </summary>
public string GetPageHtml
{
get
{
return PageString.ToString();
}
}
/// <summary>
/// 设置或获取目前页数
/// </summary>
public int PageNum
{
get
{
return PrivatePageNum;
}
set
{
if (value >= 1)
{
PrivatePageNum = value;
}
}
}
/// <summary>
/// 设置或获取最大分页数
/// </summary>
public int MaxPageSize
{
get
{