基于ASP.NET的自定義分頁顯示
摘要:本文針對WEB數據庫記錄的顯示問題,用實例討論了在ASP.NET框架下使用DataGrid控件對數據庫記錄的一種自定義分頁顯示。
關鍵詞:WEB數據庫;ASP.NET;DataGrid;分頁
引言
在用戶進行數據查詢時通常有這樣的情況,一個數據庫查詢將返回太多的行,一致不能在一頁中顯示。如果用戶正在使用一個慢的鏈接,發送特別大的數據結果可能要花很長的時間。一旦獲得了數據,用戶可能發現它不包含正確的內容,或者查詢范圍太大,沒有容易的辦法檢查完所有的結果來找到重要的信息。因此,對查詢結果分頁顯示將為用戶可管理的數據查詢提供極大的方便。分頁顯示是一種非常常見的瀏覽和顯示大量數據的方法,屬于web編程中最常處理的事件之一,現在網站基本上都提供了分頁顯示信息的功能,但大部分還是基于ASP的,而.NET平臺框架是針對各種各樣的Web應用設計的,因此本文討論了一種在ASP.NET框架下實現查詢記錄自定義分頁顯示的技術。
ASP.NET
.NET是通過平臺獨立的數據描述方法(通過XML)和通用的訪問媒介Internet來簡化用戶訪問和存儲信息的過程。
ASP.NET是Microsoft.Net框架的核心元素,是一項基于服務器的強大技術,利用它,可以為WWW站點或企業內部網創建動態可以交互的HTML頁面。ASP.NET 完全基于模塊和組件,具有很好的可擴展性和可定制性。它主要包括WebForm和WebService兩種編程模式。前者為用戶提供功能強大、外觀豐富的基于表單(Form)的可編程Web頁面;后者通過對HTTP、XML、SOAP、WSDL等Internet標準的支持提供在異構網絡環境下獲取遠程服務、鏈接遠程設備、交互遠程應用的編程界面。
通過ADO.NET鏈接、操縱數據源
在Microsoft公司推出開放式數據庫互連(ODBC)應用程序編程接口(API)以來,出現了各種各樣的數據庫訪問技術,而直到ADO.NET出現,API才能實時地給出處理效果。ADO.NET是ASP.NET應用程序用來與數據庫進行通信的技術,使你可以同關系數據庫和其他數據源進行交互。斷開的訪問是ADO.NET最重要的特性,是對ADO最大的改變。ADO.NET創建一個到數據庫的鏈接,用從數據庫中提取的信息副本填充數據集。如果改變了數據集(DataSet)中的信息,數據庫里相應表格中的信息不會改變。需要時,可以把DataSet連回最初的數據源并應用所有的改變。
ADO.NET主要依賴以下核心對象的功能。它們分為兩個組:一組對象用來存放和管理數據(例如:DataTable,DataRow和DataRelation),另一組對象用來鏈接到某個特定的數據源(例如:Connections,Commands和DataReader類)
在大多數的情況下,需要的數據是在某個數據源(例如:某個關系數據庫)中。要想對這些數據進行訪問、提取并將其插入到適當的數據對象中,就必須使用數據源對象。使用數據源對象的目的是創建一個鏈接并把相關信息移入某個DataSet或DataReader中。一種最簡單的數據庫訪問方法是:利用Command對象直接進入數據源并通過DataReader檢索只讀數據行。另一種選擇:把數據放入某個斷開鏈接的DataSet,從而在更長的時間段操作。
用DataGrid控件分頁顯示記錄
在創建鏈接和命令對象之后就要把返回的記錄顯示出來。DataGrid控件是ASP.NET中功能最強大也是最復雜的數據控件,可以用它來顯示和格式化數據表的數據,它除了內建的數據表現和方法之外,還允許用戶自己定義表現形式。分頁技術為用戶可管理的數據查找提供方便。
1、DataGrid內建分頁技術原理
DataGrid內建分頁技術很容易實現,但數據量很大時,它的方便性是以犧牲性能為代價的。如果一個用戶只要求100個頁面中每頁顯示25條記錄的第8頁的結果集,服務器只需要發送第175-200行的數據即可,而不是1-1000行的完全數據。默認的傳送方式如圖1所示。
從圖1中可以看出,DataGrid的內建分頁方法效率不高,每次請求都必須把整個查詢結果發送給Web服務器,Web服務器再把數據分成相應的頁面。利用DataGrid的內建的分頁方法盡管是很簡單的,但是,由于Web應用的無序性特征,一個用戶每次從一個頁面轉向另外一個頁面時,DataGrid對象都被銷毀并重新創建,這就意味著數據庫服務器每次都必須發送全部的結果集。
2、自定義分頁技術
那么如何通過自定義的分頁方法來實現快速處理大量數據的結果集呢?
它比DataGrid的默認分頁方法更加快速有效,因為每次請求不需要把全部的數據結果都發送到Web服務器。相反,它只需要發送每個頁面需要的那些數據集。自定義的分頁方法只返回所要檢索的那些結果集,如圖2所示。
從圖2中可以看到,數據庫每次只需要返回所要顯示的數據記錄。
在ASP.NET頁面中執行SQL命令的方法可以是直接執行也可以先將SQL命令封裝在存儲過程中,然后再頁面中執行該存儲過程。執行存儲過程比直接執行SQL命令稍微復雜一些,但能顯著提高數據庫驅動的Web站點的性能。每次從ASP.NET頁面直接執行SQL命令時,都需要SQL Server對其進行解析、編譯和優化,而存儲過程只需要進行一次解析、編譯和優化。
而這里自定義的分頁方法就是使用存儲過程來做分頁的工作,而不是由Web服務器來做。
首先,在數據庫中建立一個存儲過程,該存儲過程接受兩個輸入參數,分別是要返回數據的第一條記錄數和最后一條記錄數。要創建一個返回指定條記錄結果的存儲過程,首先必須指定返回結果集的條記錄數,這里用table變量(SQL Server 2000),table變量盡管是存儲在內存中的,但在存儲過程結束后自動釋放。創建的存儲過程如下:
---- 建立有標識符列的table變量
---- 在返回指定的@StopRow行數之后停止處理查詢
---- 插入到table變量中
---- 返回到正確的結果
參數@StartRow和@StopRow接收整數值,代表要返回的開始記錄和結束記錄,如果要在一個25條記錄的頁面中返回第8頁,我們就可以設置@StartRow為176,@StopRow為200。
table變量@t_table中定義了一個叫rownum的整數類型的列,并指定為標識符列,它將在插入數據的時候自動增加,起到排序作用。Set RowCount語句是優化性能的關鍵,它會告訴SQL Server進行限制要插入的數據,如果我們要176-200條記錄之間的數據,那么就可以不必插入大于200條記錄的數據。最后的SQL語句通過@t_table的table變量選擇rownum大于或者等于@StartRow的那些數據集,然后把它們返回到Web服務器,由Web服務器綁定到DataGrid對象。但如果瀏覽者請求的頁數越來越大,需要向table變量填充的記錄就越多,導致頁面性能有所下降。因此,性能將依賴于你計算機的硬件和你要返回的記錄數,但為了減輕數據庫和網絡傳輸的壓力,設計合理的查詢結果頁數是很見效的。
然后將為DataGrid對象編寫代碼來使用分頁技巧。DataGrid的AllowPaging、AllowCustomPaging、PageStyle屬性有助于記錄用戶的訪問狀態。首先設定AllowCustomPaging為True。我們使用SQLDataReader來裝載DataGrid對象。據性能測試表明:在構建列表顯示數據時,使用SQLDataReader比使用DataSet要快兩倍以上。
為了追求性能最佳化,設定DataGrid的EnableViewState屬性為false,因為這樣在每次與Web服務器打交道時就不必再在viewstate中存儲內容了。
當DataGrid不在viewstate中進行保存,需要添加導航按鈕來幫助用戶進行導航。
那么在頁面上增加兩個按鈕:“上一頁”和“下一頁”。要進入下一頁,就在“下一頁”按鈕上增加click事件,通過自定義分頁存儲過程請求相應的記錄。例如:如果第一頁由第1條到第25條記錄組成,那么要導航到第二頁,我們就向存儲過程的@StartRow傳遞參數26,向@StopRow傳遞參數50即可,要返回到第一頁,@StartRow和@StopRow分別為1和25。
在這里使用VB.NET編寫“下一頁”事件:
在上面的例子中,viewstate中保存的只是@StartRow和@StopRow的信息,這比在viewstate中保存整個DataGrid對象高效的多。
結束語
以上程序是在SQL Server 2000實現的,但對于其他關系型數據庫同樣適用,比如ORACLE等等。列表顯示信息的性能對瀏覽者的訪問是很重要的,設計不好的列表顯示會大大降低應用程序的性能,不管它的后端數據庫是多么快速。使用自定義分頁技術,可以避免DataGrid默認分頁機制帶來的缺陷,在.NET框架的強大沖擊下,ASP.NET已成為新一代網站開發的主流技術,因此本文討論的技術很具有實用價值。
關鍵詞:WEB數據庫;ASP.NET;DataGrid;分頁
引言
在用戶進行數據查詢時通常有這樣的情況,一個數據庫查詢將返回太多的行,一致不能在一頁中顯示。如果用戶正在使用一個慢的鏈接,發送特別大的數據結果可能要花很長的時間。一旦獲得了數據,用戶可能發現它不包含正確的內容,或者查詢范圍太大,沒有容易的辦法檢查完所有的結果來找到重要的信息。因此,對查詢結果分頁顯示將為用戶可管理的數據查詢提供極大的方便。分頁顯示是一種非常常見的瀏覽和顯示大量數據的方法,屬于web編程中最常處理的事件之一,現在網站基本上都提供了分頁顯示信息的功能,但大部分還是基于ASP的,而.NET平臺框架是針對各種各樣的Web應用設計的,因此本文討論了一種在ASP.NET框架下實現查詢記錄自定義分頁顯示的技術。
ASP.NET
.NET是通過平臺獨立的數據描述方法(通過XML)和通用的訪問媒介Internet來簡化用戶訪問和存儲信息的過程。
ASP.NET是Microsoft.Net框架的核心元素,是一項基于服務器的強大技術,利用它,可以為WWW站點或企業內部網創建動態可以交互的HTML頁面。ASP.NET 完全基于模塊和組件,具有很好的可擴展性和可定制性。它主要包括WebForm和WebService兩種編程模式。前者為用戶提供功能強大、外觀豐富的基于表單(Form)的可編程Web頁面;后者通過對HTTP、XML、SOAP、WSDL等Internet標準的支持提供在異構網絡環境下獲取遠程服務、鏈接遠程設備、交互遠程應用的編程界面。
通過ADO.NET鏈接、操縱數據源
在Microsoft公司推出開放式數據庫互連(ODBC)應用程序編程接口(API)以來,出現了各種各樣的數據庫訪問技術,而直到ADO.NET出現,API才能實時地給出處理效果。ADO.NET是ASP.NET應用程序用來與數據庫進行通信的技術,使你可以同關系數據庫和其他數據源進行交互。斷開的訪問是ADO.NET最重要的特性,是對ADO最大的改變。ADO.NET創建一個到數據庫的鏈接,用從數據庫中提取的信息副本填充數據集。如果改變了數據集(DataSet)中的信息,數據庫里相應表格中的信息不會改變。需要時,可以把DataSet連回最初的數據源并應用所有的改變。
ADO.NET主要依賴以下核心對象的功能。它們分為兩個組:一組對象用來存放和管理數據(例如:DataTable,DataRow和DataRelation),另一組對象用來鏈接到某個特定的數據源(例如:Connections,Commands和DataReader類)
在大多數的情況下,需要的數據是在某個數據源(例如:某個關系數據庫)中。要想對這些數據進行訪問、提取并將其插入到適當的數據對象中,就必須使用數據源對象。使用數據源對象的目的是創建一個鏈接并把相關信息移入某個DataSet或DataReader中。一種最簡單的數據庫訪問方法是:利用Command對象直接進入數據源并通過DataReader檢索只讀數據行。另一種選擇:把數據放入某個斷開鏈接的DataSet,從而在更長的時間段操作。
用DataGrid控件分頁顯示記錄
在創建鏈接和命令對象之后就要把返回的記錄顯示出來。DataGrid控件是ASP.NET中功能最強大也是最復雜的數據控件,可以用它來顯示和格式化數據表的數據,它除了內建的數據表現和方法之外,還允許用戶自己定義表現形式。分頁技術為用戶可管理的數據查找提供方便。
1、DataGrid內建分頁技術原理
DataGrid內建分頁技術很容易實現,但數據量很大時,它的方便性是以犧牲性能為代價的。如果一個用戶只要求100個頁面中每頁顯示25條記錄的第8頁的結果集,服務器只需要發送第175-200行的數據即可,而不是1-1000行的完全數據。默認的傳送方式如圖1所示。
![]() 圖1 DataGrid默認傳送方式 |
從圖1中可以看出,DataGrid的內建分頁方法效率不高,每次請求都必須把整個查詢結果發送給Web服務器,Web服務器再把數據分成相應的頁面。利用DataGrid的內建的分頁方法盡管是很簡單的,但是,由于Web應用的無序性特征,一個用戶每次從一個頁面轉向另外一個頁面時,DataGrid對象都被銷毀并重新創建,這就意味著數據庫服務器每次都必須發送全部的結果集。
2、自定義分頁技術
那么如何通過自定義的分頁方法來實現快速處理大量數據的結果集呢?
它比DataGrid的默認分頁方法更加快速有效,因為每次請求不需要把全部的數據結果都發送到Web服務器。相反,它只需要發送每個頁面需要的那些數據集。自定義的分頁方法只返回所要檢索的那些結果集,如圖2所示。
![]() 圖2 自定義分頁的傳送方式 |
從圖2中可以看到,數據庫每次只需要返回所要顯示的數據記錄。
在ASP.NET頁面中執行SQL命令的方法可以是直接執行也可以先將SQL命令封裝在存儲過程中,然后再頁面中執行該存儲過程。執行存儲過程比直接執行SQL命令稍微復雜一些,但能顯著提高數據庫驅動的Web站點的性能。每次從ASP.NET頁面直接執行SQL命令時,都需要SQL Server對其進行解析、編譯和優化,而存儲過程只需要進行一次解析、編譯和優化。
而這里自定義的分頁方法就是使用存儲過程來做分頁的工作,而不是由Web服務器來做。
首先,在數據庫中建立一個存儲過程,該存儲過程接受兩個輸入參數,分別是要返回數據的第一條記錄數和最后一條記錄數。要創建一個返回指定條記錄結果的存儲過程,首先必須指定返回結果集的條記錄數,這里用table變量(SQL Server 2000),table變量盡管是存儲在內存中的,但在存儲過程結束后自動釋放。創建的存儲過程如下:
create proc InsertStudents @Student_Last_Name as varchar(100) = null, @StartRow as int = null, @StopRow as int = null AS |
---- 建立有標識符列的table變量
declare @t_table table ( [rownum] [int] IDENTITY (1, 1) Primary key NOT NULL , [Student_Last_Name] [varchar] (40) , [Student_First_Name] [varchar] (20) , ) |
---- 在返回指定的@StopRow行數之后停止處理查詢
Set RowCount @StopRow |
---- 插入到table變量中
insert @t_table ( [Student_Last_Name],[Student_First_Name] ) SELECT [Student_Last_Name],[Student_First_Name] FROM Students WHERE Student_Last_Name like '%' + @Student_Last_Name like '%' ORDER BY Student_Last_Name |
---- 返回到正確的結果
SELECT * FROM @t_table WHERE rownum >= @StartRow ORDER BY rownum GO |
參數@StartRow和@StopRow接收整數值,代表要返回的開始記錄和結束記錄,如果要在一個25條記錄的頁面中返回第8頁,我們就可以設置@StartRow為176,@StopRow為200。
table變量@t_table中定義了一個叫rownum的整數類型的列,并指定為標識符列,它將在插入數據的時候自動增加,起到排序作用。Set RowCount語句是優化性能的關鍵,它會告訴SQL Server進行限制要插入的數據,如果我們要176-200條記錄之間的數據,那么就可以不必插入大于200條記錄的數據。最后的SQL語句通過@t_table的table變量選擇rownum大于或者等于@StartRow的那些數據集,然后把它們返回到Web服務器,由Web服務器綁定到DataGrid對象。但如果瀏覽者請求的頁數越來越大,需要向table變量填充的記錄就越多,導致頁面性能有所下降。因此,性能將依賴于你計算機的硬件和你要返回的記錄數,但為了減輕數據庫和網絡傳輸的壓力,設計合理的查詢結果頁數是很見效的。
然后將為DataGrid對象編寫代碼來使用分頁技巧。DataGrid的AllowPaging、AllowCustomPaging、PageStyle屬性有助于記錄用戶的訪問狀態。首先設定AllowCustomPaging為True。我們使用SQLDataReader來裝載DataGrid對象。據性能測試表明:在構建列表顯示數據時,使用SQLDataReader比使用DataSet要快兩倍以上。
為了追求性能最佳化,設定DataGrid的EnableViewState屬性為false,因為這樣在每次與Web服務器打交道時就不必再在viewstate中存儲內容了。
當DataGrid不在viewstate中進行保存,需要添加導航按鈕來幫助用戶進行導航。
那么在頁面上增加兩個按鈕:“上一頁”和“下一頁”。要進入下一頁,就在“下一頁”按鈕上增加click事件,通過自定義分頁存儲過程請求相應的記錄。例如:如果第一頁由第1條到第25條記錄組成,那么要導航到第二頁,我們就向存儲過程的@StartRow傳遞參數26,向@StopRow傳遞參數50即可,要返回到第一頁,@StartRow和@StopRow分別為1和25。
在這里使用VB.NET編寫“下一頁”事件:
Private Sub ButtonNext_Click (ByVal sender As Object, _ ByVal e As System.EventArgs) Handles ButtonNext.Click viewstate("StartRow") = viewstate("StartRow") + dgrid.PageSize viewstate("StopRow") = viewstate("StartRow") + dgrid.PageSize '運行存儲過程,返回SQLDataReader dgrid.DataSource = RunSprocReturnDR (textSt_lname.Text, textSt_fname.Text, viewstate("StartRow"),viewstate("StopRow")) dgrid.DataBind() End Sub |
在上面的例子中,viewstate中保存的只是@StartRow和@StopRow的信息,這比在viewstate中保存整個DataGrid對象高效的多。
結束語
以上程序是在SQL Server 2000實現的,但對于其他關系型數據庫同樣適用,比如ORACLE等等。列表顯示信息的性能對瀏覽者的訪問是很重要的,設計不好的列表顯示會大大降低應用程序的性能,不管它的后端數據庫是多么快速。使用自定義分頁技術,可以避免DataGrid默認分頁機制帶來的缺陷,在.NET框架的強大沖擊下,ASP.NET已成為新一代網站開發的主流技術,因此本文討論的技術很具有實用價值。