程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 分頁中的知識

分頁中的知識

編輯:C#入門知識

 概述
       分頁就是把數據分成一頁一頁的,然後再顯示出來,從這句話的理解中我們可以有多種方案:一次從數據庫中只取出當前頁面的數據,如需顯示下一頁數據,再從數據庫中取出本次頁面的數據;一次從數據庫中取出所有的數據,然後,顯示顯示當前頁面的數據,如需顯示下一頁數據,再一次從數據庫中取出所有數據,顯示下一頁數據,一次類推;一次從數據庫中取出所有的數據,然後,顯示本次頁面數據,如需顯示下一頁的數據,不需要再一次從數據庫取出數據,根據之前的數據,顯示下一頁面的數據。具體每種方案的優缺點、適用於哪種情況,在這裡就不說了,合理使用這幾種方案,可以使我們的系統更加的完美。
       下面是一些關於這幾種方案在實現過程中需要掌握的一些知識。


 GridView控件
        使用GridView控件實現數據分頁的功能,核心代碼如下:
[csharp] view plaincopyprint?
//打開分頁功能  
GridView1.AllowPaging = true;     
//確定每頁最大記錄數  
GridView1.PageSize = 2;   
//綁定數據源   
GridView1.DataSource = dt;     
GridView1.DataBind();  
 
 
//GridView控件的PageIndexChanging事件裡代碼的功能:實現點擊某頁就轉化到某頁數據  
 
 
//把要轉化到的頁數賦值給控件的PageIndex屬性  
GridView1.PageIndex = e.NewPageIndex;     
 //從新綁定數據  
…… 

//打開分頁功能
GridView1.AllowPaging = true;   
//確定每頁最大記錄數
GridView1.PageSize = 2; 
//綁定數據源
GridView1.DataSource = dt;   
GridView1.DataBind();


//GridView控件的PageIndexChanging事件裡代碼的功能:實現點擊某頁就轉化到某頁數據


//把要轉化到的頁數賦值給控件的PageIndex屬性
GridView1.PageIndex = e.NewPageIndex;   
 //從新綁定數據
……

AspNetPager分頁控件
      我們可以把分頁這個整體分為為兩個過程:分頁邏輯運算和頁面顯示。GridView控件具有整個分頁的功能,但是其分頁邏輯運算不怎麼好,所以,有了AspNetPager控件(沒有顯示頁面數據的功能),對於AspNetPager控件,其在分頁過程中用到的代碼如下:
[csharp] view plaincopyprint?
//設置總記錄數的大小  
AspNetPager.RecordCount = 10; 
//設置每頁記錄數的大小  
AspNetPager.PageSize = 2;  
 
 
//AspNetPager控件的PageChanging事件裡的代碼如下  
AspNetPager.CurrentPageIndex = e.NewPageIndex;          
//重新綁定數據  
…… 

//設置總記錄數的大小
AspNetPager.RecordCount = 10;
//設置每頁記錄數的大小
AspNetPager.PageSize = 2;


//AspNetPager控件的PageChanging事件裡的代碼如下
AspNetPager.CurrentPageIndex = e.NewPageIndex;        
//重新綁定數據
……

數據庫
       對於一次些取完所有數據的SQL代碼在這裡就不說了,需要說一下的是另一種情況:一次取記錄中一部分記錄的情況。根據要求,我們可以得出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代碼
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的一些代碼:
[sql]
--創建  
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 

--創建
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之間數據的傳遞代碼:
[csharp] 
//傳遞表頭信息  
                //方法一  
                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]);  
                } 

//傳遞表頭信息
                //方法一
                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結合,具體代碼如下
[csharp] 
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(); 
        }         
    } 

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控件,具體代碼如下:
[csharp]
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(); 
        }      
    } 

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層的代碼也沒有貼出來,所以,如果要是用上述代碼的話,還是要多多注意點。


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved