Home > C# > Collezione di supporto alla Paginazione

Collezione di supporto alla Paginazione

La paginazione dei dati è uno dei problemi classici ricorrente, soprattutto in ambito web, ma non solo. Immaginiamo di voler visualizzare una lista di 10000 elementi, ovviamente non potranno essere visualizzati tutti in una sola pagina o finestra. Per questa ragione si ricorre alla paginazione, in modo da visualizzare solo un numero limitato di elementi per pagina fornendo la possibilità di scorrere le pagine e quindi i dati, evitandone il caricamento massivo. Nel caso in cui i dati siano recuperati da database (come al 99% dei casi) dovranno essere effettuate query top k dove k è il numero massimo di elementi ritornati dalla query (grandezza della pagina) con indice in modo da avere gli x-esimi k elementi. (Es. Voglio i primi 10 elementi, per la prima pagina, poi i secondi 10 ecc.).

Prima di tutto è necessario quindi definire i parametri di paginazione, tramite la classe PagingSettings che definisce tutti le informazioni sui dati recuperati. I dati possono essere visualizzati da due punti di vista, assolutamente analoghi:

  • Numero di Elementi per pagina – Indice di Pagina
  • Indice di Scostamento – Numero massimo di elementi visualizzati

Chiramente è sempre possibile tramite calcolo passare da una visualizzazione all’altra, a patto di sapere se l’indice della prima pagina (che potrebbe essere 0 o 1).

public class PagingSettings   
{
   private readonly int _firstPage; 
   private readonly int _pageIndex; 
   private readonly int _pageSize;   
}

La scelta del criterio da utilizzare per la memorizzazione interna dello stato è assolutamente arbitraria, io ho scelto indice di pagine e grandezza della pagina, ma l’altro sarebbe assolutamente equivalente. La conversione nell’altra visualizzalizzazione è possibile tramite proprietà di solo get come segue:

public long StartIndex
{
   get { return (_pageIndex – _firstPage) * _pageSize; }
}

public int PageIndex
{
   get { return _pageIndex; }
}        

public int PageSize
{
   get { return _pageSize; }
}

In entrambe le viste il numero è ovviamente presente il PageSize definibile anche come MaxRowCount (sinonimi). La creazione di questa classe di impostazioni e stato è possibile sia da entrambi i punti di vista (due valori interi con diversa semantica), per questa ragione ho scelto di realizzare il costruttore privato e due metodi factory per i due differenti punti di vista:

public static PagingSettings CreateByPageData(int pageSize, int pageIndex)
{
   return new PagingSettings(pageSize, pageIndex, 1);
}

public static PagingSettings CreateByPageData(int pageSize, int pageIndex, int firstPage)
{
   return new PagingSettings(pageSize, pageIndex, firstPage);
}

public static PagingSettings CreateByIndexData(long startIndex, int maxRowCount)
{
   return CreateByIndexData(startIndex, maxRowCount, 1);
}

public static PagingSettings CreateByIndexData(long startIndex, int maxRowCount, int firstPage)
{
   if (startIndex == 0 && maxRowCount == 0)
      return new PagingSettings(0, 0, 0);
   return new PagingSettings(maxRowCount, (int)Math.Ceiling((double)startIndex / maxRowCount), firstPage);
}

questi si appoggiano ad altri due metodi statici di creazione a cui è possibile passare anche l’indice della prima pagina (il default è ovviamente 1)

realizzato la classe PagingSettings manca ora la collezione vera e propria che dovrà mantenere internamente lo stato (classe PagingSettings) gli elementi della pagina corrente e il numero totale di elementi. Di seguito l’interfaccia della collezione IPaginatedList<T>.

public interface IPaginatedList<T> : IList<T>
{
   bool HasNextPage { get; }
   bool HasPreviousPage { get; }
   int PageIndex { get; }
   int PageSize { get; }
   long TotalDomainObjectCount { get; set; }
   long TotalPages { get; }
}

per I dettagli dell’implementazione si rimanda al codice sorgente allegato..

Scarica Sorgente

Categories: C#
  1. 2 agosto 2010 alle 01:54 | #1

    La tua soluzione è molto carina in alternativa potevi usare jquery (ormai è una delle soluzione che meglio si adatta a moltissimi scenari e ti permette con poco di creare dei gradevoli effetti grafici).

    • massimoalbertin
      2 agosto 2010 alle 08:55 | #2

      La mia idea è di utilizzare questa collezione come classe di appoggio lato server, il che non esclude poi l’utilizzo di jquery. Mi spiego meglio immagina di voler utilizzare una delle tante griglie basate su jquery (es. io uso flexigrid), lato server ho necessità di realizzare metodi per il recupero delle informazioni con paginazione (magari inserite all’interno di un repository di base per l’accesso ai dati). Queste informazioni possono essere memorizzate all’interno di una PaginatedList prima di essere convertite in un oggetto serializzabile con Json da spedire alla specifica griglia.

  2. 2 agosto 2010 alle 15:21 | #3

    Certo, assolutamente sono d’accordo ;-)

  1. No trackbacks yet.

Lascia un Commento

Fill in your details below or click an icon to log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Log Out / Modifica )

Foto Twitter

You are commenting using your Twitter account. Log Out / Modifica )

Foto di Facebook

You are commenting using your Facebook account. Log Out / Modifica )

Connecting to %s

Follow

Get every new post delivered to your Inbox.