惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
J
Java Code Geeks
S
SegmentFault 最新的问题
L
LangChain Blog
M
MIT News - Artificial intelligence
Stack Overflow Blog
Stack Overflow Blog
IT之家
IT之家
量子位
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
雷峰网
雷峰网
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
MongoDB | Blog
MongoDB | Blog
Microsoft Security Blog
Microsoft Security Blog
腾讯CDC
H
Help Net Security
阮一峰的网络日志
阮一峰的网络日志
Jina AI
Jina AI
N
Netflix TechBlog - Medium
A
About on SuperTechFans
博客园 - 叶小钗
美团技术团队
人人都是产品经理
人人都是产品经理
D
DataBreaches.Net

博客园 - shaoyun

Python抓取百度搜索结果 多线程采集器的核心代码 ThinkPHP2.1模版使用笔记 - 模版嵌套/AJAX级联 畅想无线显示技术 OAuth协议分析一 通用四级联动下拉列表 通用手动分页方法 通用三级联动下拉列表 Indy 邮件发送的例子 Indy 组件学习注意事项 利用API的消息发送程序原理 Delphi DLL 的编写 Discuz!NT3.1 子目录安装实例 Delphi 托盘程序示例 Delphi ADO 学习笔记 SQL获取数据表的空间占用 C#编写简单的系统服务管理器 很久没有写博了,发发挠骚 Twitter被封后教你继续访问的方法
ASP.Net 一步一步学习分页(适合初学者) - shaoyun - 博客园
shaoyun · 2010-12-18 · via 博客园 - shaoyun

1. 方式一,原始分页:

适应性比较好,但代码结构凌乱,分页链接的生成参见 <<通用手动分页方方法>> ,包含用到的GetPageLinks()函数

SQLHelper db = new SQLHelper(g_ConnStr);

db.Open();

DataSet dt = db.ExecuteDataSet("SELECT * FROM [DCMS_Article] where channel_id=16 order by art_date desc");

if (dt.Tables[0].Rows.Count != 0)

{

    int nPageSize = 10;

    int nShowNum = 5;

    int nRecord = dt.Tables[0].Rows.Count;

    int CurPage = Utils.ToInt(Request.QueryString["page"]);

    PagedDataSource fenye = new PagedDataSource();

    fenye.AllowPaging = true;

    fenye.DataSource = dt.Tables[0].DefaultView;

    fenye.PageSize = nPageSize;

    int PageCount = fenye.PageCount;

    CurPage = CurPage == 0 ? 1 : CurPage;

    CurPage = CurPage > PageCount ? PageCount : CurPage;

    fenye.CurrentPageIndex = CurPage - 1;

    rpt_list_news.DataSource = fenye;

    lblPageLinks.Text = PageCount > 0 ? Utils.GetPageLinks(nRecord, nPageSize, nShowNum) : "";

}

else

{

    rpt_list_news.DataSource = dt;

}

rpt_list_news.DataBind();

db.Close();

2.方式二,换个方式简化调用:

稍微简化了调用方式,但使用有一定局限性

private void Bind()

{

    SQLHelper db = new SQLHelper(g_ConnStr);

    db.Open();

    string strsql="SELECT * FROM [DCMS_Article] where channel_id=16 order by art_date desc" ;

    int nPageSize = 2;

    int nShowNum = 5;

    int nRecord =0;

    int CurPage = Utils.ToInt(Utils.Get( "page"));

    DataSet dt = db.GetPagedDataSet(strsql, CurPage, nPageSize, out nRecord);

    rpt_list_news.DataSource = dt.Tables[0];

    lblPageLinks.Text = Utils.GetPageLinks(nRecord, nPageSize, nShowNum);

    rpt_list_news.DataBind();

    db.Close();

}

用到的GetPagedDataSet函数如下

public DataSet GetPagedDataSet(string SQLString, int CurPage, int PageSize, out int RecordCount)

{

    DataSet ds = new DataSet();

    using (SqlDataAdapter da = new SqlDataAdapter(SQLString, conn))

    {

        SQLString = System.Text.RegularExpressions.Regex.Replace(SQLString, "order by.*" , "");

        RecordCount = (int)ExecuteScalar(string.Format("select count(*) from ({0}) as temp", SQLString));

        //内部校正一下当前页的页码

        PageSize = PageSize > 0 ? PageSize : 1;

        int nPageCount = RecordCount % PageSize == 0 ? RecordCount / PageSize : (RecordCount / PageSize) + 1;

        CurPage = CurPage > nPageCount ? nPageCount : CurPage;

        CurPage = CurPage > 0 ? CurPage : 1;

        int startRow = (CurPage - 1) * PageSize;

        da.Fill(ds,startRow, PageSize, "table");

    }

    return ds;

}

3.初次封装简化参数:

尝试再次改进,方法二中代码看起来已经不那么乱了,但是需要提前设定多个分页参数,调用多了修改起来就比较麻烦,而且很明显的缺点适用性不好,如果我们将分页的具体操作封装就会简化许多,看封装后的调用

private void Bind()

{

    SQLHelper db = new SQLHelper(g_ConnStr);

    db.Open();  

    PageHelper pager = new PageHelper();

    pager.CurrPage =  Utils.ToInt(Utils .Get("page"));

    int nRecord= 0;

    string strsql = "SELECT * FROM [DCMS_Article] where channel_id=16 order by art_date desc" ;

    DataSet dt = db.GetPagedDataSet(strsql, pager.CurrPage, pager.PageSize, out nRecord);

    rpt_list_news.DataSource = dt.Tables[0];

    rpt_list_news.DataBind();

    pager.RecordCount = nRecord;

    lblPageLinks.Text = pager.GetPageLinks();

    db.Close();

}

清晰了不少,PageHelper类提供了分页的必须参数,参数设定了默认值,另外将 Utils.GetPageLinks() 函数封装在里面内部调用默认参数,也避免参数手动输入,PageHelper 每个人都有不同的实现,大抵都类似

这个PageHelper根据查询结果重新分页,跟第一次的分页方式相同,PageHelper增加了GetPagedDataSource函数

private void Bind()

{

    SQLHelper db = new SQLHelper(g_ConnStr);

    db.Open();

    string strsql = "SELECT * FROM [DCMS_Article] where channel_id=16 order by art_date desc" ;

    DataSet dt = db.ExecuteDataSet(strsql);

    PageHelper pager = new PageHelper();

    pager.CurrPage = Utils.ToInt(Utils.Get("page"));

    rpt_list_news.DataSource = pager.GetPagedDataSource(dt);

    rpt_list_news.DataBind();

    lblPageLinks.Text = pager.GetPageLinks();

    db.Close();

}

public object GetPagedDataSource(DataSet dsSrc)

{

    object retDataSource = new object();

    if (dsSrc.Tables[0].Rows.Count != 0)

    {

        System.Web.UI.WebControls.PagedDataSource fenye = new System.Web.UI.WebControls.PagedDataSource();

        fenye.AllowPaging = true;

        fenye.DataSource = dsSrc.Tables[0].DefaultView;

        fenye.PageSize = this.PageSize;

        this._RecordCount = dsSrc.Tables[0].Rows.Count;

        this._PageCount = fenye.PageCount;

        _CurrPage = _CurrPage == 0 ? 1 : _CurrPage;

        _CurrPage = _CurrPage > _PageCount ? _PageCount : _CurrPage;

        fenye.CurrentPageIndex = _CurrPage - 1;

        retDataSource = fenye;

    }

    return retDataSource;

}

这次倒是感觉跟平常的调用没啥区别了,就是多次查询让人很不爽,其次数据多了也增加开销,这里暂时先不尝试存储过程分页,再试试看能改进到什么程度

5.综合一下

数据源的获取放在PageHelper类中不是很好还是放在DBHeler中,其实我还是比较喜欢 SqlDataAdapter 来分页, PagedDataSource 分页则必须先查询一次再分页,奈何无论采取哪种方式获取记录总数总是个问题

private void Bind()

{

    SQLHelper db = new SQLHelper(g_ConnStr);

    db.Open();

    string strsql = "SELECT * FROM [DCMS_Article] where channel_id=16 order by art_date desc" ;

    PageHelper pager = new PageHelper();

    pager.CurrPage = Utils.ToInt(Utils.Get("page"));

    rpt_list_news.DataSource = db.GetPagedDataSource(strsql, ref pager);

    rpt_list_news.DataBind();

    lblPageLinks.Text = pager.GetPageLinks();

    db.Close();

}

调用算是比较简单了,要是能解决查询记录总数的问题,那就好多了,下面是DBHelper中的函数实现

public object GetPagedDataSource(string strsql, int CurrPage, int PageSize, out int RecordCount)

{

    object retDataSource = new object();

    DataSet dsSrc = ExecuteDataSet(strsql);

    RecordCount = 0;

    int PageCount = 0;

    if (dsSrc.Tables[0].Rows.Count != 0)

    {

        System.Web.UI.WebControls. PagedDataSource fenye = new System.Web.UI.WebControls.PagedDataSource ();

        fenye.AllowPaging = true;

        fenye.DataSource = dsSrc.Tables[0].DefaultView;

        fenye.PageSize = PageSize;

        RecordCount = dsSrc.Tables[0].Rows.Count;

        PageCount = fenye.PageCount;

        CurrPage = CurrPage == 0 ? 1 : CurrPage;

        CurrPage = CurrPage > PageCount ? CurrPage : CurrPage;

        fenye.CurrentPageIndex = CurrPage - 1;

        retDataSource = fenye;

    }

    return retDataSource;

}

//这个简化了参数调用

public object GetPagedDataSource(string strsql, ref PageHelper pager )

{

    int nRecord = 0;

    object retobj= GetPagedDataSource(strsql, pager.CurrPage, pager.PageSize, out nRecord);

    pager.RecordCount= nRecord;

    return retobj;

}