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.
- Articolo precedente Transazioni
- Articolo successivo Prestazioni: migliorare problemi di lentezza di un database