Data paging: Paginazione dei risultati

Grazie al linguaggio ASP.NET, estrarre records da una tabelladi un database e riportarli in forma tabulare su una paginaweb è piuttosto semplice. Basta impostare laproprietà DataSource nell' oggetto DataGrid ad unDataSet contenente i records. Se il numero dei recordsè maggiore della dimensione dello schermo, saràpossibile sfruttare il meccanismo di paginazione contenutonella DataGrid. Ottimo metodo questo, senza dubbio, chediventa però lento nel caso in cui il database da cuiestrarre i records risulti di grandi dimensioni.Vieneimpiegato infatti diverso tempo non tanto nell'estrazione dei records, quanto piuttosto nella lorosuddivisione in pagine. Ond' evitare noiose attese aivisitatori, è bene ricorrere al quella che in gergoviene chiamata "effective data paging"; questarichiede due parametri, PageSize e CurrentPage ed èpossibile solo facendo uso di una stored procedure. In questasi andrà a lavorare con due nuove funzioni T-SQL;grazie a ROW_NUMBER si potranno numerare i records in manieracrescente, dal primo pubblicato all' ultimo; travite OVERinvece, si potrà specificare la colonna cheavrà un valore numerico sequenziale. Con SQL 2005,come per SQL 2000, è necessario inserire i dati in unatabella temporanea, che non occuperà comunque tantospazio, ne rallenterà vistosamente le operazioni. Eccoil codice della stored procedure:

CREATE PROCEDURE [dbo].[sproc_get_clients]    @PageSize [int] = -1,    @CurrentPage [int] = -1WITH EXECUTE AS CALLERAS    SELECT  ROW_NUMBER() OVER(ORDER BY client_name ASC) AS rownum,client_id,client_name  INTO#tmp_tbl_client  FROMtbl_client  CREATE UNIQUE CLUSTERED INDEXidx_uc_rownum  ON#tmp_tbl_client(rownum)  SELECTrownum,client_id,client_name,  FROM #tmp_tbl_client  WHERErownum BETWEEN (@CurrentPage-1)*@PageSize+1 AND @CurrentPage*@PageSize  ORDER BYclient_name ASC

Ond' evitare di riprogrammare lo stesso oggetto ADO.NETpiù e più volte, viene in aiuto l'Enterprise Library, scaricabile da qui. Nell' ultima versione risulta indipendente daldatabase e non vengono richieste modifiche nel trasporto dicodice Oracle su SQL Server e viceversa. Per maggioriinformazioni sul prodotto, invito ad effettuare ricerche suGoogle, salterà alla luce una vastà mole dimateriale.

Nel nostro esempio andremo a lavorare su due livelli: quellodei dati si connetterà al database, attivando lastored procedure, mentre quello della presentazionegestirà la DataGrid.

Implementare il DataGrid: mentre si impaginano i recordsall' interno dello spazio della pagina, la sorgente daticonterrà l' esatto numero di records cheverrà mostrato in ciascuna pagina. Dobbiamo integrarviuna paginazione standard, cosa non difficile da fare, dalmomento che richiede unicamente tre parametri. Nella classedella griglia dati bisognerà impostare laproprietà AllowCustomPaging a "True" ,così che si possa definire il conteggio degli elementivirtuali.

La proprietà VirtualItemCount fa in modo che ilDataGrid impagini il numero di records da noi richiesto,invece di impaginare tutti quelli contenuti. Ecco comerisulterà la griglia, lato codice:

Nel Data Layer:

Public Function getClientCount() As Integer    Dim clientCount As Integer = 0    Try  Dim dbCommandWrapper As DBCommandWrapper = _objDatabase.GetSqlStringCommandWrapper( _"SELECT COUNT(client_id) FROM tbl_client")  clientCount = Convert.ToInt32(objDatabase.ExecuteScalar(dbCommandWrapper))    Catch ex As Exception  Throw New Exception("Error getting client count: " & ex.Message)    End Try    Return clientCountEnd Function

Nel Presentation Layer:

Function getItemCount()    Dim itemCount As Integer = 0    Dim client As New clientHandler    Try  client.useDefaultDatabase()  itemCount = client.getClientCount()    Catch ex As Exception  messageLabel.Text = "Error getting number of records: " & ex.Message    End Try    Return itemCountEnd FunctionclientDataGrid.VirtualItemCount = getItemCount()

Infine, per impostare la pagina corrente basterà:

Sub clientDataGrid_PageIndexChanged(ByVal sender As Object,    ByVal e As DataGridPageChangedEventArgs)    clientDataGrid.CurrentPageIndex = e.NewPageIndex    Call bindGrid(clientDataGrid.PageSize, e.NewPageIndex + 1)End Sub

A questo punto non resta che rilegare la griglia allasorgente dati:

Sub bindGrid(ByVal pageSize As Integer, ByVal currentPage As Integer)    Dim client As New clientHandler    Try  client.useDefaultDatabase()  Dim objDataSet As DataSet = Nothing  objDataSet = client.getClients(pageSize, currentPage)  clientDataGrid.DataSource = objDataSet.Tables(0)  clientDataGrid.DataBind()    Catch ex As Exception  messageLabel.Text = "Error binding grid: " & ex.Message    End TryEnd Sub

Il risultato sarà una griglia dati in grado dimuoversi rapidamente in mezzo a milioni e milioni di records.

Per avere il quadro riassuntivo del tutto, èdisponibile il download dellasorgente dell' esempio sopra proposto.