2015-02-19 12 views
5

Iam cercando di applicare Impaginazione alla mia applicazione MVC. Iam usando stoccaggio tavolo AzureAggiungi Impaginazione MVC e Azure tabella

Ecco che cosa ho provato: -

public List<T> GetPagination(string partitionKey, int start, int take) 
    { 
     List<T> entities = new List<T>(); 

     TableQuery<T> query = new TableQuery<T>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionKey.ToLower())); 
     entities = Table.ExecuteQuery(query).Skip(start).Take(take).ToList(); 

     return entities; 

    } 

Controller: -

public ActionResult Index() 
     { 

      key= System.Web.HttpContext.Current.Request[Constants.Key]; 
      if (String.IsNullOrEmpty(key)) 
       return RedirectToAction("NoContext", "Error"); 

      var items= _StorageHelper.GetPagination(key,0,3); 
      ItemCollection itemCollection = new ItemCollection(); 
      itemCollection .Items= Mapper.Map<List<ItemChart>, List<ItemModel>>(items); 
      itemCollection .Items.ForEach(g => g.Object = g.Object.Replace(key, "")); 


      return View(itemCollection); 
     } 

questo momento mi dà i primi 3 voci da miei dati. Ora, come posso mostrare e implementare "Precedente" e "Successivo" per mostrare il resto delle voci nella pagina successiva? Come posso implementare il resto del controller e della pagina HTML?

Qualsiasi aiuto è apprezzato.

risposta

12

Quando si tratta di impaginazione, ci sono alcune cose da considerare:

  • Non tutti gli operatori LINQ (e, a sua volta le opzioni di query OData) sono supportati per servizio al tavolo. Ad esempio, Skip non è supportato. Per un elenco degli operatori supportati, vedere questo link: https://msdn.microsoft.com/en-us/library/azure/dd135725.aspx.
  • Il modo impaginazione funziona con servizio al tavolo è che quando si esegue una query il vostro tavolo per andare a prendere alcuni dati, il numero massimo di soggetti che possono essere restituiti dal servizio al tavolo è 1000. Non c'è alcuna garanzia che sempre di 1000 soggetti saranno restituiti. Potrebbe essere inferiore a 1000 o anche 0 a seconda di come stai interrogando. Tuttavia, se sono disponibili più risultati, il Servizio tabella restituisce qualcosa chiamato Continuation Token. È necessario utilizzare questo token per recuperare il prossimo set di risultati dal servizio di tabella. Si prega di consultare questo link per ulteriori informazioni sul timeout e sull'impaginazione delle query: https://msdn.microsoft.com/en-us/library/azure/dd135718.aspx.

Prendendo questi due fattori in considerazione, non si può davvero implementare una soluzione di paging in cui un utente può saltare direttamente a una determinata pagina (ad esempio, l'utente è seduto a pagina 1 e quindi l'utente non può andare a pagina 4). Al massimo è possibile implementare la prossima pagina, la pagina precedente e il tipo di funzionalità della prima pagina.

Per implementare il tipo di funzionalità next page, archiviare il token di continuazione restituito dal servizio di tabella e utilizzarlo nella query.

Per implementare il tipo di funzionalità , è necessario memorizzare tutti i token di continuazione restituiti in un array o qualcosa e tenere traccia di quale pagina è attualmente attiva un utente (che sarebbe l'indice di pagina corrente). Quando un utente vuole andare alla pagina precedente, si ottiene il token di continuazione per l'indice precedente (cioè l'indice della pagina corrente - 1) e lo si utilizza nella query.

Per implementare first page tipo di funzionalità, basta emettere la query senza seguito token.

fare dare un'occhiata a ExecuteQuerySegmented metodo bagagli Client Library se si desidera implementare l'impaginazione.

UPDATE

Si prega di vedere il codice di esempio. Per semplicità, ho solo mantenuto la prima pagina e la funzionalità della pagina successiva:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Microsoft.WindowsAzure.Storage.Auth; 
using Microsoft.WindowsAzure.Storage.Blob; 
using Microsoft.WindowsAzure.Storage; 
using Microsoft.WindowsAzure.Storage.Queue; 
using Microsoft.WindowsAzure.Storage.Table; 
namespace TablePaginationSample 
{ 
    class Program 
    { 
     static string accountName = ""; 
     static string accountKey = ""; 
     static string tableName = ""; 
     static int maxEntitiesToFetch = 10; 
     static TableContinuationToken token = null; 
     static void Main(string[] args) 
     { 
      var cloudStorageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true); 
      var cloudTableClient = cloudStorageAccount.CreateCloudTableClient(); 
      var table = cloudTableClient.GetTableReference(tableName); 
      Console.WriteLine("Press \"N\" to go to next page\nPress \"F\" to go first page\nPress any other key to exit program"); 
      var query = new TableQuery().Take(maxEntitiesToFetch); 
      var continueLoop = true; 
      do 
      { 
       Console.WriteLine("Fetching entities. Please wait...."); 
       Console.WriteLine("-------------------------------------------------------------"); 
       var queryResult = table.ExecuteQuerySegmented(query, token); 
       token = queryResult.ContinuationToken; 
       var entities = queryResult.Results; 
       foreach (var entity in entities) 
       { 
        Console.WriteLine(string.Format("PartitionKey = {0}; RowKey = {1}", entity.PartitionKey, entity.RowKey)); 
       } 
       Console.WriteLine("-------------------------------------------------------------"); 
       if (token == null)//No more token available. We've reached end of table 
       { 
        Console.WriteLine("All entities have been fetched. The program will now terminate."); 
        break; 
       } 
       else 
       { 
        Console.WriteLine("More entities available. Press \"N\" to go to next page or Press \"F\" to go first page or Press any other key to exit program."); 
        Console.WriteLine("-------------------------------------------------------------"); 
        var key = Console.ReadKey(); 
        switch(key.KeyChar) 
        { 
         case 'N': 
         case 'n': 
          continue; 
         case 'F': 
         case 'f': 
          token = null; 
          continue; 
         default: 
          continueLoop = false; 
          break; 
        } 
       } 
      } while (continueLoop); 
      Console.WriteLine("Press any key to terminate the application."); 
      Console.ReadLine(); 
     } 
    } 
} 
+0

Grazie per la risposta. Iam abbastanza nuovo a questo concetto. Potete spiegarmelo per favore con un esempio? – HappyCode1990

+0

Aggiornato la mia risposta con codice di esempio. Per favore dai un'occhiata. HTH. –

+1

Va notato che questa soluzione non funzionerà sempre come speri. Se la query impiega più di 5 secondi per l'esecuzione, otterrai un risultato con meno dei risultati massimi E un token di continuazione. Ho una soluzione simile implementata nella mia applicazione e talvolta ottengo pagine vuote e devo premere "Avanti" più volte per arrivare ai primi risultati. – Mike