天天看點

ASP.Net2.0 分頁顯示簡述(附源代碼)

分頁顯示是 ASP.Net 中常常用到的一個功能,不但能提供更好的使用者體驗,而且更重要的是可以大大減少網絡通訊量,因為每一次頁面加載隻需要讀取“一頁”的資料量。但是 ASP.Net 2.0 中的 GridView 雖然可以通過把 AllowPaging 屬性設為 True 來進行分頁顯示:

ASP.Net2.0 分頁顯示簡述(附源代碼)

但如果沒有定義支援分頁檢索資料的方法的話,這隻是在顯示上的分頁,用戶端還是一次性載入了全部資料,并沒有達到減少網絡負擔。 要實作真正的分頁顯示就需要結合 ObjectDataSource 控件來“自定義”,注意 ObjectDataSource 的這幾個屬性:

ASP.Net2.0 分頁顯示簡述(附源代碼)

EnablePaging : ObjectDataSource 的 SelectCommand 是否支援分頁 MaximumRowsParameterName 和 StartRowIndexParameterName :是指 SelectCommand 所指定的方法中用于分頁的兩個參數名稱,前者用于指定每頁的記錄數,後者用于指定每頁開始行的索引值。 這兩個值是可以根據具體調用的方法參數來更改,上圖中顯示的是預設值。 SelectCountMehtod :用于指定獲得記錄總行數的方法,要不怎麼知道有多少頁啊:)   流程: 大體上資料從資料源(如 SQL Server )到頁面顯示的流程如下圖所示:

ASP.Net2.0 分頁顯示簡述(附源代碼)

“自定義”就是要從底層一步步做起,以 SQL Server 2005 示例資料庫 AdventureWorks 為例,現在要實作這樣一個功能:根據 ShipMethodID 分頁檢索 Sales.SalesOrderHeader 表中的資料。   一、 存儲過程 在 SQL Server 2005 中使用 ROW_NUMBER() 函數可以直接得到行數,相比較 SQL Server 2000 中子查詢的方法,不僅更加簡便而且大大提高了執行效率。 -- 獲得目前頁的表資料 CREATE PROC [Sales].[GetOrderHeadeList] ( @shipMethodID INT, @maximumRows INT, @startRowIndex INT ) AS SET NOCOUNT ON SELECT SalesOrderID       ,OrderDate       ,DueDate       ,SubTotal       ,TaxAmt       ,Freight       ,TotalDue  FROM (SELECT ROW_NUMBER() OVER (ORDER BY OrderDate DESC) Row               ,SalesOrderID              ,OrderDate               ,DueDate               ,[Status]               ,TaxAmt               ,Freight               ,TotalDue           FROM Sales.SalesOrderHeader          WHERE ShipMethodID=@shipMethodID) SalesOrder  WHERE Row>@startRowIndex AND ROW<=@startRowIndex+@maximumRows 還需要一個存儲過程來獲得總行數: -- 獲得總記錄數 CREATE PROC [Sales].[GetTotalNumberOfOrderHeader] ( @shipMethodID INT ) AS SET NOCOUNT ON SELECT COUNT(*)  FROM Sales.SalesOrderHeader  WHERE ShipMethodID=@shipMethodID   二、 資料通路層對象 調用存儲過程讀取資料,這裡沒什麼特别的地方:     public class OrderHeader:IOrderHeader     {         #region IOrderHeader 成員           public List<OrderHeaderInfo> GetOrderHeaderList(int shipMethodID, int maximumRows, int startRowIndex)         {             SqlConnection conn = new SqlConnection                 (ConfigurationManager.ConnectionStrings["AdventureWorksConnectionString"].ConnectionString);             SqlCommand cmd = new SqlCommand("Sales.GetOrderHeaderList", conn);             cmd.CommandType = CommandType.StoredProcedure;               cmd.Parameters.Add("@shipMethodID", SqlDbType.Int).Value = shipMethodID;             cmd.Parameters.Add("@maximumRows", SqlDbType.Int).Value = maximumRows;             cmd.Parameters.Add("@startRowIndex", SqlDbType.Int).Value = startRowIndex;               List<OrderHeaderInfo> list=new List<OrderHeaderInfo>();               conn.Open();             SqlDataReader dr = cmd.ExecuteReader();             while (dr.Read())             {                 list.Add(new OrderHeaderInfo(dr.GetInt32(0), dr.GetDateTime(1), dr.GetDateTime(2),                     dr.GetDecimal(3), dr.GetDecimal(4), dr.GetDecimal(5), dr.GetDecimal(6)));             }             dr.Close();             conn.Close();               return list;         }           public int GetTotalNumberOfOrderHeader(int shipMethodID)         {             SqlConnection conn = new SqlConnection                 (ConfigurationManager.ConnectionStrings["AdventureWorksConnectionString"].ConnectionString);             SqlCommand cmd = new SqlCommand("Sales.GetTotalNumberOfOrderHeader", conn);             cmd.CommandType = CommandType.StoredProcedure;               cmd.Parameters.Add("@shipMethodID", SqlDbType.Int).Value = shipMethodID;               conn.Open();             int result = (int)cmd.ExecuteScalar();             conn.Close();               return result;         }           #endregion } 三、 業務邏輯層對象 通過工廠方法獲得資料通路層執行個體,調用讀取方法:     public class OrderHeader     {         private IOrderHeader orderHeader = DataAccess.CreateOrderHeader();           public List<OrderHeaderInfo> GetOrderHeaderList(int shipMethodID, int maximumRows, int startRowIndex)         {             return orderHeader.GetOrderHeaderList(shipMethodID, maximumRows, startRowIndex);         }           public int GetTotalNumberOfOrderHeader(int shipMethodID, int maximumRows, int startRowIndex)         {             return orderHeader.GetTotalNumberOfOrderHeader(shipMethodID);         } } 注意GetTotalNumberOfOrderHeader這個方法,即ObjectDataSource控件的SelectCountMethod要指定的值,該值為方法名稱且不能指定參數,是以該方法的參數應與SelectCommand所指定的方法參數相一緻,否則運作時會抛出異常。   四、 表示層(這裡指ASP.Net頁面) GridView 的設定很簡單,最基本的,把 AllowPaging 設為 True 即可:

ASP.Net2.0 分頁顯示簡述(附源代碼)

ObjectDataSource 控件除了設定 SelectMothod 方法外,特别注意對開頭所說的四個屬性的設定:

ASP.Net2.0 分頁顯示簡述(附源代碼)
ASP.Net2.0 分頁顯示簡述(附源代碼)
ASP.Net2.0 分頁顯示簡述(附源代碼)

EnablePaging 設為 True ,指定 SelectCountMethod 方法。     運作結果

ASP.Net2.0 分頁顯示簡述(附源代碼)

使用斷點調試,會發現每次隻從資料庫讀取 10 條記錄,如果不使用自定義分頁,那麼每次需讀取近萬條資料!大大節省了每一次的通訊量。

源代碼下載下傳,包含生成存儲過程的T-SQL,注意修改一下web.config中的連接配接字元串值,檔案夾Web是網站項目,其他為類庫項目,建立解決方案添加一下:

PagingData.rar

原創文章,希望對大家有所幫助,不當之處請及時指正:)   資料通路相關教程,很多人推薦過了,還是值得在推薦一下: http://www.asp.net/Learn/DataAccess/ 英文不是很難,圖文并茂,還有 VB 和 C# 源代碼 <script type=text/javascript> // </script> Feedback # re: ASP.Net2.0 分頁顯示簡述(附源代碼)  回複  更多評論    2007-05-06 10:19 by wzsst 用了資料庫分頁,GridView的排序功能還能不能用? # re: ASP.Net2.0 分頁顯示簡述(附源代碼)  回複  更多評論    2007-05-06 11:19 by 徐鴻翼 隻有資料源支援IEnumerable接口才可以使用GridView的排序功能如DataView、DataTable和DataSet。但即使把讀取到的資料轉換到以上三種類型,排序也僅僅是針對目前頁的資料。   可以通過增加一個排序參數來實作,修改一下存儲過程: CREATE PROC [Sales].[GetOrderHeaderList] ( @shipMethodID INT, @sortField NVARCHAR(4000), @maximumRows INT, @startRowIndex INT ) AS SET NOCOUNT ON SELECT SalesOrderID       ,OrderDate       ,DueDate       ,SubTotal       ,TaxAmt       ,Freight       ,TotalDue  FROM (SELECT ROW_NUMBER()                OVER (ORDER BY CASE @sortField                       WHEN 'SubTotal' THEN SubTotal                       WHEN 'TaxAmt'   THEN TaxAmt                       WHEN 'Freight' THEN Freight                       WHEN 'TotalDue' THEN TotalDue                        END) Row               ,SalesOrderID               ,OrderDate               ,DueDate               ,SubTotal               ,TaxAmt               ,Freight               ,TotalDue           FROM Sales.SalesOrderHeader          WHERE ShipMethodID=@shipMethodID)SalesOrder  WHERE Row>@startRowIndex AND ROW<=@startRowIndex+@maximumRows 在 GridView 的 Sorting 事件中傳入參數即可  

繼續閱讀