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(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