2015-09-01 12 views
6

Le tabelle di archiviazione di Azure dispongono tutte di una colonna timestamp. In base alla documentazione here, il modo in cui elencare per eliminare da una tabella di memoria è selezionare un'entità, quindi eliminarla.Come eliminare tutte le entità con un timestamp di oltre 1 giorno di età dalla tabella di archiviazione di Azure?

Qualcuno sa come eliminare qualsiasi entità da una tabella di memoria in base a un confronto con datetime sul valore di timestamp utilizzando il codice?

EDIT:

Sulla base del parere dato che ho scritto il seguente codice. Tuttavia, genera un'eccezione Richiesta non valida sulla mia chiamata table.ExecuteQuery (rangeQuery). Qualche consiglio?

StorageCredentials creds = new StorageCredentials(logAccountName, logAccountKey); 
    CloudStorageAccount account = new CloudStorageAccount(creds, useHttps: true); 

    CloudTableClient client = account.CreateCloudTableClient(); 

    CloudTable table = client.GetTableReference(LogTable); 

    TableQuery<CloudQuerySummary> rangeQuery = new TableQuery<CloudQuerySummary>() 
     .Where(TableQuery.GenerateFilterCondition("Timestamp", QueryComparisons.LessThan 
     , DateTime.Now.AddHours(- DateTime.Now.Hour).ToString())); 


    TableOperation deleteOperation; 
    // Loop through the results, displaying information about the entity. 
    foreach (CloudQuerySummary entity in table.ExecuteQuery(rangeQuery)) 
    { 
     deleteOperation = TableOperation.Delete(entity); 

     table.Execute(deleteOperation); 
    } 

EDIT 2

Ecco il codice finale di lavoro per tutti coloro che sceglie di copiare/fare riferimento a esso.

public void DeleteLogsNotFromToday() 
{ 
    StorageCredentials creds = new StorageCredentials(logAccountName, logAccountKey); 
    CloudStorageAccount account = new CloudStorageAccount(creds, useHttps: true); 

    CloudTableClient client = account.CreateCloudTableClient(); 

    CloudTable table = client.GetTableReference(LogTable); 

    TableQuery<CloudQuerySummary> rangeQuery = new TableQuery<CloudQuerySummary>() 
     .Where(TableQuery.GenerateFilterConditionForDate("Timestamp", QueryComparisons.LessThan 
     , DateTime.Now.AddHours(-DateTime.Now.Hour))); 

    try 
    { 

     TableOperation deleteOperation; 
     // Loop through the results, displaying information about the entity. 
     foreach (CloudQuerySummary entity in table.ExecuteQuery(rangeQuery)) 
     { 
      deleteOperation = TableOperation.Delete(entity); 

      table.Execute(deleteOperation); 
     } 
    } 
    catch (Exception ex) 
    { 
     throw; 
    } 

} 
+0

vedere la risposta modificata. –

risposta

3

Si dovrà fare una scansione delle partizioni per farlo, come entità sono indicizzati solo sulla loro PartitionKey e RowKey.

Nel collegamento del tutorial che hai pubblicato, guarda la sezione Recupera un intervallo di entità in una partizione. Dopo aver ottenuto le entità che si desidera eliminare, si eseguirà un'operazione di tabella per eliminarle.

Se non si desidera eliminarli uno per uno, è possibile creare un'operazione di eliminazione batch (a condizione che tutte le entità da eliminare abbiano la stessa chiave di partizione). Il link sopra indica anche come costruire un'operazione batch.

In alternativa, se non si desidera eseguire una scansione della tabella, è necessario memorizzare il riferimento di data (ad esempio, memorizzare la data in millisecondi come RowKey) e quindi utilizzarlo per filtrare le entità che è necessario eliminare in base a un confronto data-ora (qualcosa di simile a THIS)

UPDATE: Penso che il problema è in questa linea: DateTime.Now.AddHours(- DateTime.Now.Hour).ToString()

partire dalla documentation:

la Tim Estamp proprietà è un valore diDateTime che viene mantenuto sul lato server per registrare il tempo un'entità dell'ultima modifica

Si sta tentando di confrontare una proprietà DateTime con una stringa. Non sono un esperto di C#, ma non mi sembra un paragone valido.

+2

Luis quasi ha risposto alla domanda. Un'altra cosa che vorrei menzionare è: utilizzare TableQuery.GenerateFilterConditionForDate invece di TableQuery.GenerateFilterCondition e non chiamare ToString() sull'oggetto DateTime. –

+0

Grazie a tutti e due. Pubblicherò il mio codice di lavoro finale per i futuri visitatori. –

0

Se si utilizza Slazure questo tipo di lavoro diventa più semplice, il codice seguente dovrebbe funzionare anche con l'edizione Light (gratuita).

using SysSurge.Slazure; 
using SysSurge.Slazure.Linq; 
using SysSurge.Slazure.Linq.QueryParser; 

namespace TableOperations 
{ 
    public class LogOperations 
    { 
     public static void DeleteOldLogEntities() 
     { 
      // Get a reference to the table storage, example just uses the development storage 
      dynamic storage = new QueryableStorage<DynEntity>("UseDevelopmentStorage=true"); 

      // Get a reference to the table named "LogTable" 
      QueryableTable<DynEntity> logTable = storage.LogTable; 
      var query = logTable.Where("Timestamp > @0", DateTime.UtcNow.AddDays(-1)); 

      // Delete all returned log entities 
      foreach (var entity in query) 
       logTable.Delete(entity.PartitionKey, entity.RowKey); 
     } 
    } 
} 

Full disclosure: I codice Slazure.

+0

è disponibile tramite il nodo? o solo C#. – kkap

+0

@kkap Slazure è solo per sviluppatori .NET, mi dispiace. –

Problemi correlati