2015-09-01 4 views
6

Azure-Speichertabellen haben alle eine Timestamp-Spalte. Basierend auf der Dokumentation here können Sie aus einer Speichertabelle löschen, indem Sie eine Entität auswählen und dann löschen.Wie löscht man alle Objekte mit einem Zeitstempel, der mehr als 1 Tag alt ist, aus der Azure Storage Table?

Kann jemand eine Entität aus einer Speichertabelle basierend auf einem Datetime-Vergleich auf dem Timestamp-Wert mithilfe von Code löschen?

EDIT:

Basierend auf den Rat gegeben ich den folgenden Code geschrieben haben. Es wird jedoch eine Ausnahmefehler bei meinem Aufruf von table.ExecuteQuery (rangeQuery) ausgelöst. Irgendein Rat?

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

Hier ist der letzte Arbeits Code für jeden, der/Referenz zu kopieren wählt.

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

siehe bearbeitete Antwort. –

Antwort

3

In Kürze erhalten Sie eine Partition-Scan zu tun, das zu tun, als Entitäten nur auf ihre PartitionKey und RowKey indiziert sind.

In der Tutorial-Link, den Sie veröffentlicht haben, sehen Sie sich den Abschnitt Abrufen eines Bereichs von Elementen in einer Partition. Sobald Sie die Entitäten erhalten, die Sie löschen möchten, führen Sie eine Tabellenoperation aus, um sie zu löschen.

Wenn Sie sie nicht einzeln löschen möchten, können Sie eine Stapellöschoperation erstellen (vorausgesetzt, alle zu löschenden Entitäten haben denselben Partitionsschlüssel). Der obige Link weist auch an, wie eine Stapeloperation erstellt wird.

Wenn Sie keinen Tabellenscan durchführen möchten, sollten Sie alternativ die Datumsreferenz speichern (z. B. das Datum in Millisekunden als Zeilenschlüssel speichern) und dann die zu löschenden Entitäten anhand dieser Elemente filtern ein Datum Zeitvergleich (etwas ähnliches wie THIS)

UPDATE: ich denke, das Problem in dieser Linie ist: DateTime.Now.AddHours(- DateTime.Now.Hour).ToString()

Wie aus den documentation:

The Tim eStamp Eigenschaft ist ein Datetime Wert, der auf der Server-Seite gehalten wird, um die Zeit ein Unternehmen wurde zuletzt aufnehmen modifizierte

Sie versuchen, eine DateTime Eigenschaft mit einem String zu vergleichen. Ich bin kein C# -Experte, aber das sieht für mich nicht nach einem gültigen Vergleich aus.

+2

Luis beantwortete fast die Frage. Eine weitere Sache, die ich erwähnen möchte, ist: Verwenden Sie TableQuery.GenerateFilterConditionForDate anstelle von TableQuery.GenerateFilterCondition, und rufen Sie ToString() nicht für das DateTime-Objekt auf. –

+0

Danke an euch beide. Ich werde meinen endgültigen Arbeitscode für zukünftige Besucher veröffentlichen. –

0

Wenn Sie Slazure verwenden, wird diese Art von Arbeit einfacher, der folgende Code sollte auch mit der Light (free) Edition arbeiten.

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); 
     } 
    } 
} 

Volle Enthüllung: Ich kodierte Slazure.

+0

ist über Knoten verfügbar? oder nur C#. – kkap

+0

@kkap Slazure ist nur für .NET-Entwickler, sorry. –

Verwandte Themen