分页中的知识

 概述

       分页就是把数据分成一页一页的,然后再显示出来,从这句话的理解中我们可以有多种方案:一次从数据库中只取出当前页面的数据,如需显示下一页数据,再从数据库中取出本次页面的数据;一次从数据库中取出所有的数据,然后,显示显示当前页面的数据,如需显示下一页数据,再一次从数据库中取出所有数据,显示下一页数据,一次类推;一次从数据库中取出所有的数据,然后,显示本次页面数据,如需显示下一页的数据,不需要再一次从数据库取出数据,根据之前的数据,显示下一页面的数据。具体每种方案的优缺点、适用于哪种情况,在这里就不说了,合理使用这几种方案,可以使我们的系统更加的完美。
       下面是一些关于这几种方案在实现过程中需要掌握的一些知识。

 GridView控件

        使用GridView控件实现数据分页的功能,核心代码如下:
//打开分页功能
GridView1.AllowPaging = true;    
//确定每页最大记录数
GridView1.PageSize = 2;  
//绑定数据源 
GridView1.DataSource = dt;    
GridView1.DataBind(); 


//GridView控件的PageIndexChanging事件里代码的功能:实现点击某页就转化到某页数据


//把要转化到的页数赋值给控件的PageIndex属性
GridView1.PageIndex = e.NewPageIndex;    
 //从新绑定数据
……

AspNetPager分页控件

      我们可以把分页这个整体分为为两个过程:分页逻辑运算和页面显示。GridView控件具有整个分页的功能,但是其分页逻辑运算不怎么好,所以,有了AspNetPager控件(没有显示页面数据的功能),对于AspNetPager控件,其在分页过程中用到的代码如下:
//设置总记录数的大小
AspNetPager.RecordCount = 10;
//设置每页记录数的大小
AspNetPager.PageSize = 2; 


//AspNetPager控件的PageChanging事件里的代码如下
AspNetPager.CurrentPageIndex = e.NewPageIndex;         
//重新绑定数据
……

数据库

       对于一次些取完所有数据的SQL代码在这里就不说了,需要说一下的是另一种情况:一次取记录中一部分记录的情况。根据要求,我们可以得出SQL语句中应该包含每一页的记录数和页面示数,并且,我们还有保证他的正确性。具体代码如下:

--通用的SQL代码
select top 每页显示的记录数 *  from A 
where id not in
             (select top (当前的页数-1) * 每页显示的记录数 id from A order by id desc)
order by id desc       
        解释:这个是比较通用的方法,主要意思是:总数为100人,按照顺序排好,A选前20个人,B选前10个人,从A从取出10个跟B中人不同的人。
-- 另一种SQL语句如下:
with tempTB as (  
  SELECT ROW_NUMBER() OVER (ORDER BY id desc)AS Row,   
  ...  
)
SELECT * FROM tempTB where Row between @startIndex and @endIndex 
      解释:这个SQL代码我们需要知道两个点:CTE和row_number() over (partition by column order by column)。

CTE

        CTE是公共表表达式,其产生的最大好处就是提升了SQL代码的可读性,当然,一定程度上也是提高了系统的性能,它是一个存储结果集的内存表(数据太多的话也会用到虚拟内存),且结果集只对其后一句SQL语句有效,并且,这个后一句SQL语句可以多次出现该结果集,CTE主要是递归的运用,下面是关于CTE的一些代码:
--创建
with CTE_Test1
as
(
    select id,title,content from news
),    --引用多个不同的结果集的CET,可以同时创建多个
CTE_Test2
as
(
    select id,categoryId from news
)

--使用;CTE_Test只能被紧跟其后一条SQL语句一次或多次访问
select * from CTE_Test1 as a
inner join CTE_Test2 as b
on a.id = b.id    
order by a.id desc


--创建(递归)
with CTE_Test(id,categoryId,title)
as
(
    --基本语句
    select id,categoryId,title from news
    union all
    --递归语句
    select news.id,news.categoryId,news.title from news inner  join  CTE_Test on news.id = CTE_Test.id
)

--使用
select * from CTE_Test 
option(maxrecursion 2)     --指定最大递归次数为2

       临时表是为了记录大量的中间集;视图是为了简化复杂的联表查询;表变量是为了快速记录少量的中间集;CET是为了SQL代码的可读性。以上是笔者认为它们的主要作用,具体就不解释了。


row_number() over (partition by column order by column)

        这个是一个函数,具体的作用就是在查询的结果集中添加一个字段,并且顺序的写出序号;partition by column的作用是是该函数分块进行书写相应的序号,例:A块和B块的序号的书写都是从1开始的。



DataTable向DataTalbe之间数据传递

        当采用一次访问数据,数次使用数据的方案时,我们的基本操作就是,把总数据放到一个DataTable中,每一页的数据放到另一个DataTable中,我们绑定的时候,绑定每一页的数据,下面是DataTable和DataTable之间数据的传递代码:
//传递表头信息
                //方法一
                for (int i = 0; i < dt1.Columns.Count; i++)
                {
                    dt2.Columns.Add(dt1.Columns[i].ColumnName);
                }
                //方法二
                //复制一个相同的对象
                dt2 = dt1.Copy();
                //清空里面的数据
                dt2.Rows.Clear();                          
                //方法三
                //复制一个对象,但该对象里没有相应的数据
                dt2 = dt1.Clone();


//传递具体数据信息
                for (int i = 0; i < dt1.Rows.Count; i++)
                {
                    //方法一:添加一行数据
                    DataRow drq = dt2.NewRow();
                    drq.ItemArray = dt1.Rows[i].ItemArray;
                    dt2.Rows.Add(drq);


                    //方法二:添加一行数据
                    //dt2.ImportRow(dt.Rows[0]);
                }
        通过逻辑运算,找到从哪一行开始赋值。


实例1

       下面是采用每次从数据库取出一页数据的方案的实例,采用GridView和AspNetPager结合,具体代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
namespace Web
{
    public partial class Test1 : System.Web.UI.Page
    {
        DataTable dt = new DataTable ();
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                //总的记录数是多少
                anp.RecordCount = 4;
                //每页显示的记录数
                anp.PageSize = 2;


                //获得数据
                GetSource();
                //绑定数据
                BandSource();
            }
        }


        //获得源数据
        private void GetSource()
        {
            SqlConnection cn = new SqlConnection();
            cn.ConnectionString = "Data Source=ip地址;Initial Catalog=数据库;User ID=登陆名;Pwd=密码";
            cn.Open();


            string strSql = "select top (@每页记录数) *  from news where id not in (select top (@当前页减一的记录和) id from news order 


by id desc) order by id desc";


            SqlCommand cmd = new SqlCommand(strSql,cn);
           
            SqlParameter[] sqlParams = new SqlParameter[] { new SqlParameter("@每页记录数", anp.PageSize), new SqlParameter("@当前页减


一的记录和", (anp.CurrentPageIndex - 1) * anp.PageSize) };


            cmd.Parameters.AddRange(sqlParams);
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            da.Fill(dt);
        }


        //绑定源数据
        private void BandSource()
        {
            //绑定数据            
            GridView1.DataSource = dt;    //设定数据源
            GridView1.DataBind();    //绑定数据源
        }


        //索引页发生改变
        protected void AspNetPager1_PageChanging(object src, Wuqi.Webdiyer.PageChangingEventArgs e)
        {
            //获得当前索引页示数
            anp.CurrentPageIndex = e.NewPageIndex;      


            //重新获得数据,绑定数据
            GetSource();
            BandSource();
        }        
    }
}



实例2

       该实例是多次访问数据库,每一次返回所有数据的那个方案,采用GridView控件,具体代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BLL;
using System.Data;
using System.Data.SqlClient;


namespace Web
{
    public partial class Test1 : System.Web.UI.Page
    {
        DataTable dt = new DataTable ();
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {   
                //开启分页的功能
                GridView2.AllowPaging = true;
                //每页的大小为1
                GridView2.PageSize = 1;


                //绑定数据,并显示第一页
                GridView2.DataSource = new NewsManger().SelectNewsAll();
                GridView2.DataBind();
            }
        }      
  
        //索引页发生改变        
        protected void GridView2_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            //设置显示的页码
            GridView1.PageIndex = e.NewPageIndex;  
            //从新绑定数据
            GridView2.DataSource = new NewsManger().SelectNewsAll();
            GridView2.DataBind();
        }     
    }
}

       实例1和2的前台界面设计没有贴出相应的代码,还有,实例2运用的是经典3层架构,BLL层的代码也没有贴出来,所以,如果要是用上述代码的话,还是要多多注意点。


总结

       GridView控件一旦绑定并选中了某页,那么,其他页的的数据你是无法再通过GridView显示的,除非你再一次的绑定选中某页。       
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值