飘易博客(作者:Flymorn)
订阅《飘易博客》RSS,第一时间查看最新文章!
飘易首页 | 留言本 | 关于我 | 订阅Feed

ASP.NET高效率的分页算法实现方法(非控件)

Author:flymorn Source:飘易
Categories:Asp/Asp.Net PostTime:2013-8-30 11:46:34
正 文:
    使用ASP.NET开发web程序时,经常会遇到数据列表页需要分页的问题。在ASP.NET里,分页可以通过绑定数据控件实现,如GridView、DataList、Repeater、ListView等这些数据控件都可以实现分页效果。它们之间的一些对比:

    GridView:开发效率高,自带分页、排序、但占用资源高。
    DataList:分页和排序需要手动编码,分页需要使用 PagedDataSource类实现。
    Repeater:不提供任何布局,开发周期长。

    注意,使用这些控件的时候,ViewState功能必须打开(即 EnableViewState="true" 在NET里,默认是打开的),因为如果关闭了ViewState视图状态,在点击下一页这些跳转按钮时,.net页面是记不住当前状态的。

    但是,重点来了:
    这些使用控件的分页方法基本是采用了javascript的方法实现的跳转
    比如 DataList 配合 PagedDataSource类实现的代码如下:
    
<a id="lnkbtnNext" href="javascript:__doPostBack('lnkbtnNext','')">下一页</a>

    GridView自带的分页代码如下:
    
<a href="javascript:__doPostBack('GridView1','Page$2')" style="color:#333333;">第2页</a>

    而我们知道,作为web网站程序开发,搜索引擎对页面的(前台)js的链接并不敏感,也不会抓取和索引js里的链接,这就会造成一个严重的情况,那就是列表页从第二页开始,都无法抓取并索引,大量网页无法出现在搜索引擎的结果页里。

    因此,飘易设计了一个比较通用的高效率的asp.net分页算法的实现,实现方法如下:

    在 default.aspx 前台页面里放入代码(注意,必须添加  runat="server" 标记):
<div id="divlist" runat="server"></div>

    在 default.aspx.cs 后台代码页面里编写代码:

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data.SqlClient;

public partial class _Default: System.Web.UI.Page
{
    comClass CC = new comClass();//实例化

    protected void Page_Load(object sender, EventArgs e)
    {//初始化
        if (!IsPostBack)
        {
            string html = getListData();
            divlist.InnerHtml = html;
        }
    }

    public static bool IsNum(String str)
    {//判断是否是ASCII纯数字
        if (str == null || str == "") return false;
        for (int i = 0; i < str.Length; i++)
        {
            if (str[i] < '0' || str[i] > '9')
                return false;
        }
        return true;
    }

    public string getListData()
    {//绑定数据
        string html = "";
        SqlConnection conn = CC.getConn();
        conn.Open();
        SqlCommand cmd;
        SqlDataReader dr;
        try
        {
            int page = 1;
            string page_get = Request["page"]; //获取当前页
            if (IsNum(page_get)) page = Convert.ToInt32(page_get); 
            int pagesize = 5; //每页多少个
            int TotalRecords, TotalPages;

            //总记录数
            cmd = new SqlCommand("select count(*) from data ", conn);
            dr = cmd.ExecuteReader();
            dr.Read();
            TotalRecords = Int32.Parse(dr[0].ToString());
            dr.Close();
            cmd.Dispose();
            //总页数
            if (TotalRecords % pagesize == 0) TotalPages = TotalRecords / pagesize;
            else TotalPages = TotalRecords / pagesize + 1;
            //当前页
            if (page < 1) page = 1;
            if (page > TotalPages) page = TotalPages;

            //---核心分页算法---
            string sql = "select top " + pagesize + " * from data order by id desc";
            if (page > 1) sql = "select top " + pagesize + " * from data where id<(SELECT Min(id) FROM (SELECT TOP " + pagesize * (page - 1) + " id FROM data ORDER BY id desc) AS T) order by id desc";
            cmd = new SqlCommand(sql, conn);
            dr = cmd.ExecuteReader();
            while (dr.Read())
            {
                html += dr["id"].ToString() + "、" + dr["title"].ToString() + "<br />";
            }
            dr.Close();
            cmd.Dispose();

            //分页代码
            string cfile = Request.Path; //当前请求的虚拟路径
            string pagestr = "\r\n<div class='page_fenye'><a href='" + cfile + "'>首页</a> ";
            for (int i=1; i<=TotalPages ; i++ )
            {
                if (i == page) pagestr += " <span>" + i + "<span> ";
                else
                {
                    if (Math.Abs(page - i) < 8)
                    {
                        if (i == 1) pagestr += " <a href='" + cfile + "'>" + i + "</a> ";
                        else pagestr += " <a href='" + cfile + "?page=" + i + "'>" + i + "</a> ";
                    }
                }
            }
            pagestr += " <a href='" + cfile + "?page=" + TotalPages + "'>尾页</a> ";
            pagestr += " <span>第" + page + "/" + TotalPages + "页, 总共" + TotalRecords + "条</span></div>";
            html += pagestr;
        }
        catch (Exception ex) { html = "异常错误:" + ex.ToString(); }
        finally { conn.Close(); }
        return html;
    }

}

    上面的代码里,都应标注了一些解释,请自行参考。

【参考:】
1、ASP的高效率的分页算法
2、PHP MySQL高效分页:子查询分页
作者:flymorn
来源:飘易
版权所有。转载时必须以链接形式注明作者和原始出处及本声明。
上一篇:Linux VPS如何挂载硬盘(VM技术)
下一篇:Chrome插件:Cookies一键清除工具发布!
2条评论 “ASP.NET高效率的分页算法实现方法(非控件)”
1 lichsky
2013-9-17 22:31:19
"comClass"呢?
2 飘易
2013-9-19 12:36:35
to:lichsky

comclass 类只是定义了一些数据库连接语句,可以自行补充。
发表评论
名称(*必填)
邮件(选填)
网站(选填)

记住我,下次回复时不用重新输入个人信息
© 2007-2010 飘易博客 Www.Piaoyi.Org 原创文章版权由飘易所有