iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

0
Modern Web

淺談資料庫&ASP.net&C# 入門系列 第 35

[iT鐵人賽Day35]ASP.NET-使用者控制項-分頁的用法

Web Forms使用者控制項

在ASP.NET中沒有內建的分頁控制項,但可以從GridView屬性的AllowPaging設定為True,就可以完成分頁,但使用內建的分頁功能,資料量小的話還好,若資料量大的話,效能會變得很不好,原因是GridView內建的是一次從資料庫取得所有資料,若資料量一大讀取速度就會變慢,而且GridView的AllowPaging我也沒研究過,之後再研究看看XD

然後其實在ASP.NET中可以自製一個控制項,使用方法就是建立一個「Web Forms使用者控制項」。並將HTML、CSS等寫到裡面,就可以完成一個自製的控制項,拖曳到自己的Web頁面就可以使用了。

使用自製控制項的話,就可以想顯示幾筆資料就跟資料庫要幾筆資料就好(使用CTE和ROW_NUMBER()),總資料量大也沒關係的,跟GridView內建的分頁功能相比,效能相對比較好。

本篇的目的與web form環境

現在已有一個GridView已經與資料庫取得資料了,並且顯示,資料表叫做[ORID_data],不過由於資料料很多,我們需要有分頁,讓使用者體驗可以比較好,頁面也比較乾淨整齊。

今天要使用一個現成的分頁控制項,並且讓它可以與SQL SERVER連接,在網頁上正常使用。

那就開始ㄅ

創立Web Forms使用者控制項

我們先創一個「Web Forms使用者控制項」其名為GridView_Page1

https://ithelp.ithome.com.tw/upload/images/20191006/20119925zoMqMqzEmJ.png

Literal控制項

建立後,從工具箱拉一個Literal控制項到GridView_Page1.ascx,並替ID命名為litpage1。
Literal控制項之後寫會員權限分配管理時在作介紹囉XD

寫入分頁的程式碼

寫入分頁的HTML程式碼。

然後創一個CSS樣式表,貼上寫好的分頁CSS,並在GridView_Page1.ascx控制項內link CSS。

拖曳分頁控制項

完成分頁的控制項後,就可以直接當成工具,用拖曳的方式拉到需要分頁功能的aspx頁面上,我將它放在GridView控制項的下方。

https://ithelp.ithome.com.tw/upload/images/20191006/20119925LIEOUOnLX9.png

接分頁參控制項的參數

通常分頁控制項要填寫的會有三個參數

1.每頁顯示的資料數量
2.資料總數量
3.分頁的網址參數(ex:第二頁就是aspx?page=2)

假設現在分頁控制項要填入的參數如下:

那麼首先先limit及totalitems先隨便填入一個值,然後呼叫此副程式,先測試看看是否有分頁出現。

 public void Pagination()
        {   
        //每頁數量
         GridView_Page1.limit = 3; 
        //資料總量
         GridView_Page1.totalitems = 300;
        //連結文字,例:pagination.aspx?page=foo=bar
         GridView_Page1.targetpage = "orid_main.aspx"; 
        //顯示分頁控制項 
         GridView_Page1.showPageControls();
        }

分頁有成功出現,且也按照設定出現共300筆資料及100頁。

https://ithelp.ithome.com.tw/upload/images/20191006/20119925OzydZplwnz.png

然後注意到網址,剛進入頁面時。

https://ithelp.ithome.com.tw/upload/images/20191006/20119925hmRFdzr83h.png

按下第5頁時。

https://ithelp.ithome.com.tw/upload/images/20191007/20119925ny0Vvm3KGq.png

抓取每分頁網址上的參數

從上圖會發現一開始在第一頁時,網址的參數並不會有Page=1。

所以先在Page_Load建立一個存網址是第幾頁的變數,使用三元運算子,假如是NULL就是1,不然就看第幾頁就是第幾頁。

int page = Request["page"]==null?1: Convert.ToInt32(Request["page"]);

取得真正的資料總數量

現在需要抓到資料庫內真正的資料總數量,並交給totalitems輸入,需使用DataReaderDataSet(DataTable)來取得資料,並放在totalitems的值。

使用DataTable的方式,SQL使用COUNT()來取得總筆數:

    //取得與資料庫的聯繫
string getconfig = System.Web.Configuration.WebConfigurationManager
              .ConnectionStrings["ConnectionStrings的NAME"].ConnectionString;
   //建立與資料庫的通道
          SqlConnection getConnection = new SqlConnection(getconfig);
   //下取得總數量的SQL語法      
          SqlCommand command = new SqlCommand($"SELECT  count(*) FROM     ORID_data  ", getConnection);
          
   //取得資料庫資料       
          SqlDataAdapter loginAdapter = new SqlDataAdapter(command);
   //創立準備存放資料的記憶體資料集 
          DataTable user = new DataTable();
   //將取得的資料存入記憶體資料集中     
          loginAdapter.Fill(user);
          
          

totalitems(總筆量)就可以放上取得的資料總筆數。

GridView_Page1.totalitems = Convert.ToInt32(user.Rows[0][0]);

假設我想每頁顯示16筆資料。
GridView_Page1.limit = 16;

GridView與分頁的聯動

切換分頁時要讓GridView上的資料會跟著分頁做變化,那麼就需要使用到SQL中暫存的CTEROW_NUMBER()的排序方法。

先在SQL Server中測試看看是否抓的到資料

with cte as (select ROW_NUMBER() OVER (ORDER BY id ASC) as ROW_ID ,* from ORID_data )

select * from cte where ROW_ID >= 1 and ROW_ID <=16

顯示結果只會出現ROW_ID範圍內16筆資料

https://ithelp.ithome.com.tw/upload/images/20191007/201199254z9RP4RX21.png

那麼現在只需要將ROW_ID的範圍改成網址上的page參數分頁公式就可以成功在每個分頁抓到需要顯示的資料。

ROW_ID >= [分頁中的第一筆] and ROW_ID <= [分頁中的最後一筆]

還記得在上面抓取每分頁網址上的參數時,我們有設一個參數取得網址的page參數ㄇ,原因是假設按到第二分頁時page=2 ;第三分頁page=3以此類推。

int page = Request["page"]==null?1: Convert.ToInt32(Request["page"]);

公式如下:

ROW_ID >= [分頁中的第一筆] and ROW_ID <= [分頁中的最後一筆]

條件:每頁顯示16筆,所以
第一頁的第一筆是 1 ;第一頁的最後一筆是16
第二頁的第一筆是 17 ;第二頁的最後一筆是32

分頁的變數是 page

可得知:

[分頁中的第一筆]= (page-1) * [每頁顯示的筆數]+1

[分頁中的最後一筆]= page * [每頁顯示的筆數]

所以SQL語法就可以寫:

with cte as (select ROW_NUMBER() OVER (ORDER BY id ASC) as ROW_ID ,* from ORID_data )

select * from cte where ROW_ID >= **(page-1) * 16+1** and ROW_ID <= **page*16**

讓GridView取得資料並顯示,如下:

  //取得網址參數
 int page = Request["page"] == null ? 1 : Convert.ToInt32(Request["page"]);
 
           //與資料庫的連接
            string config = System.Web.Configuration.WebConfigurationManager
                .ConnectionStrings["ORIDConnectionString"].ConnectionString;
                
            //建立與資料庫的通道    
            SqlConnection connection = new SqlConnection(config);
            
            //SQL語法
            SqlCommand command = new SqlCommand($"with cte as (select ROW_NUMBER() OVER (ORDER BY id ASC) as ROW_ID ,* from ORID_data )\r\n\r\nselect * from cte where ROW_ID >= {(page-1) * 16+1} and ROW_ID <= {page*16} ", connection);
            
            //使用DataTable
            
            //取得資料庫資料  
            SqlDataAdapter Adapter = new SqlDataAdapter(command);
            
            //創立準備存放資料的記憶體資料集
            DataTable user = new DataTable();
            
            //將取得的資料存入記憶體資料集中
            Adapter.Fill(user);
            
            //控制項的資料來源是從user記憶體資料集
            GridView1.DataSource = user; 
            
            //資料與控制項繫結
            GridView1.DataBind(); 

結語

運用使用者控制項達成分頁的功能,484比想像中來得簡單,比較麻煩的應該是要做出自製的分頁控制項XDD


上一篇
[iT鐵人賽Day34]SQL Server 實用的排序函數 ROW_NUMBER()
下一篇
[iT鐵人賽Day36]SQL Server 找出最新日期的所有資料
系列文
淺談資料庫&ASP.net&C# 入門36

尚未有邦友留言

立即登入留言