热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ASP.NET高性能分页代码

ASP.NET高性能分页代码
最近给分页快搞死,记得之前曾经发过修改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;

/// 
/// 扩展连接字符串
/// 

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("");
    }
    /// 
    /// 得到生成的HTML
    /// 

    public string GetHtml
    {
        get
        {
            return InsertString.ToString();
        }
    }
    /// 
    /// 得到生成的分页HTML
    /// 

    public string GetPageHtml
    {
        get
        {
            return PageString.ToString();
        }
    }
    /// 
    /// 设置或获取目前页数
    /// 

    public int PageNum
    {
        get
        {
            return PrivatePageNum;
        }
        set
        {
            if (value >= 1)
            {
                PrivatePageNum = value;
            }
        }
    }
    /// 
    /// 设置或获取最大分页数
    /// 

    public int MaxPageSize
    {
        get
        {
            return PrivateMaxPageSize;
        }
        set
        {
            if (value >= 1)
            {
                PrivateMaxPageSize = value;
            }
        }
    }
    /// 
    /// 设置或获取每次显示最大页数
    /// 

    public int MaxPages
    {
        get
        {
            return PrivateMaxPages;
        }
        set
        {
            PrivateMaxPages = value;
        }
    }
    /// 
    /// 设置或获取数据总数
    /// 

    public int DateCount
    {
        get
        {
            return PrivateCount;
        }
        set
        {
            PrivateCount = value;
        }
    }
    /// 
    /// 获取数据总页数
    /// 

    public int AllPage
    {
        get
        {
            return PrivateAllPage;
        }
    }
    /// 
    /// 初始化分页
    /// 

    public void Pagination()
    {
        PageString = new StringBuilder("");
//得到总页数
        PrivateAllPage = (int)Math.Ceiling((decimal)PrivateCount / (decimal)PrivateMaxPageSize);
//防止上标或下标越界
        if (PrivatePageNum > PrivateAllPage)
        {
            PrivatePageNum = PrivateAllPage;
        }
//滚动游标分页方式
        int LeftRange, RightRange, LeftStart, RightEnd;
        LeftRange = (PrivateMaxPages + 1) / 2-1;
        RightRange = (PrivateMaxPages + 1) / 2;
        if (PrivateMaxPages >= PrivateAllPage)
        {
            LeftStart = 1;
            RightEnd = PrivateAllPage;
        }
        else
        {
            if (PrivatePageNum <= LeftRange)
            {
                LeftStart = 1;
                RightEnd = LeftStart + PrivateMaxPages - 1;
            }
            else if (PrivateAllPage - PrivatePageNum < RightRange)
            {
                RightEnd = PrivateAllPage;
                LeftStart = RightEnd - PrivateMaxPages + 1;
            }
            else
            {
                LeftStart = PrivatePageNum - LeftRange;
                RightEnd = PrivatePageNum + RightRange;
            }
        }

//生成页码列表统计
        PageString.Append(...);

        StringBuilder PreviousString = new StringBuilder("");
//如果在第一页
        if (PrivatePageNum > 1)
        {
            ...
        }
        else
        {
            ...
        }
//如果在第一组分页
        if (PrivatePageNum > PrivateMaxPages)
        {
            ...
        }
        else
        {
            ...
        }
        PageString.Append(PreviousString);
//生成中间页
        for (int i = LeftStart; i <= RightEnd; i++)
        {
//为当前页时
            if (i == PrivatePageNum)
            {
                ...
            }
            else
            {
                ...
            }
        }
        StringBuilder LastString = new StringBuilder("");
//如果在最后一页
        if (PrivatePageNum < PrivateAllPage)
        {
            ...
        }
        else
        {
            ...
        }
//如果在最后一组
        if ((PrivatePageNum + PrivateMaxPages) < PrivateAllPage)
        {
            ...
        }
        else
        {
            ...
        }
        PageString.Append(LastString);
    }
    /// 
    /// 生成Tag分类表格
    /// 

    public void TagTable(ExDataRow myExDataRow)
    {
        InsertString.Append(...);
    }


调用方法:
代码如下:

//得到分页设置并放入Session
        ExRequest myExRequest = new ExRequest();
        myExRequest.PageSession("Tag_", new string[] { "page", "size" });
//生成Tag分页
        ExStringBuilder Tag = new ExStringBuilder();
        //设置每次显示多少条纪录
        Tag.MaxPageSize = Convert.ToInt32(Session["Tag_size"]);
        //设置最多显示多少页码
        Tag.MaxPages = 9;
        //设置当前为第几页
        Tag.PageNum = Convert.ToInt32(Session["Tag_page"]);
        string[][] myNamenValue = new string[2][]{
            new string[]{"MaxPageSize","PageNum","Count"},
            new string[]{Tag.MaxPageSize.ToString(),Tag.PageNum.ToString()}
        };
//调用存储过程
        DataTable myDataTable = mySQL.BatchGetDB("Tag_Page_Name_Select", myNamenValue, "Count");
        Tag.DateCount = (int)mySQL.OutputCommand.Parameters["@Count"].Value;
        Tag.Pagination();

        HeadPage.InnerHtml = FootPage.InnerHtml = Tag.GetPageHtml;

        for (int i = 0, j = myDataTable.Rows.Count; i < j; i++)
        {
            Tag.TagTable(new ExDataRow(myDataTable.Rows[i]));
        }
        TagBox.InnerHtml = Tag.GetHtml;


处理页码到Session的方法就不提供了,没有很大关.调用存储过程返回参数和纪录的方法和之前我写的批量数据操作方法差不多的,只需要定义一个输出方式.

目前我想这些代码还会有瑕疵,等项目后期代码审查的时候再强化吧,我想说的一点就是不要被那些拖来拖去的东西迷惑了,那样对自己永远都没有提高,要抱着知其然,知其所以然的态度去做一件事情,对自己的帮助才会明显. 
推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 数据库(外键及其约束理解)(https:www.cnblogs.comchenxiaoheip6909318.html)My ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 本文介绍了指针的概念以及在函数调用时使用指针作为参数的情况。指针存放的是变量的地址,通过指针可以修改指针所指的变量的值。然而,如果想要修改指针的指向,就需要使用指针的引用。文章还通过一个简单的示例代码解释了指针的引用的使用方法,并思考了在修改指针的指向后,取指针的输出结果。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • ASP.NET2.0数据教程之十四:使用FormView的模板
    本文介绍了在ASP.NET 2.0中使用FormView控件来实现自定义的显示外观,与GridView和DetailsView不同,FormView使用模板来呈现,可以实现不规则的外观呈现。同时还介绍了TemplateField的用法和FormView与DetailsView的区别。 ... [详细]
  • 本文介绍了一种解析GRE报文长度的方法,通过分析GRE报文头中的标志位来计算报文长度。具体实现步骤包括获取GRE报文头指针、提取标志位、计算报文长度等。该方法可以帮助用户准确地获取GRE报文的长度信息。 ... [详细]
author-avatar
手机用户2502854133
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有