【问题标题】:How to delete all entities with a timestamp more than 1 day old from Azure Storage Table?如何从 Azure 存储表中删除时间戳超过 1 天的所有实体?
【发布时间】:2015-09-01 15:57:03
【问题描述】:

Azure 存储表都有一个时间戳列。根据文档here,列出的从存储表中删除的方法是选择一个实体,然后将其删除。

有谁知道如何使用代码根据时间戳值的日期时间比较从存储表中删除任何实体?

编辑:

根据给出的建议,我编写了以下代码。但是,它会在我的 table.ExecuteQuery(rangeQuery) 调用中引发错误请求异常。有什么建议吗?

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

编辑 2

这是任何选择复制/引用它的人的最终工作代码。

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

}

【问题讨论】:

  • Great =) 记得按分区键分组,1..100个批量删除,降低交易成本。

标签: c# azure azure-table-storage


【解决方案1】:

您必须进行分区扫描才能做到这一点,因为实体仅根据其 PartitionKey 和 RowKey 编制索引。

在您发布的教程链接中,查看检索分区中的一系列实体部分。获得要删除的实体后,您将执行表操作以删除它们。

如果不想一个一个删除,可以创建批量删除操作(前提是所有要删除的实体都具有相同的分区键)。上面的链接也说明了如何构造一个批处理操作。

或者,如果您不想进行表扫描,则应存储日期引用(例如,将日期以毫秒为单位存储为 RowKey),然后使用它来过滤您需要基于删除的实体日期时间比较(类似于THIS

更新:我认为问题出在这一行: DateTime.Now.AddHours(- DateTime.Now.Hour).ToString()

来自documentation

Timestamp 属性是一个 DateTime 值,在 服务器端记录实体最后一次修改的时间

您正在尝试将DateTime 属性与字符串进行比较。我不是 C# 专家,但这在我看来并不是一个有效的比较。

【讨论】:

  • Luis 几乎回答了这个问题。我还想提一提的是:使用 TableQuery.GenerateFilterConditionForDate 而不是 TableQuery.GenerateFilterCondition,并且不要针对 DateTime 对象调用 ToString()。
  • 谢谢你们俩。我会为未来的访问者发布我的最终工作代码。
【解决方案2】:

如果您使用Slazure,这种工作会变得更容易,下面的代码应该也适用于 Light(free) 版本。

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

完全披露:我编写了 Slazure。

【讨论】:

  • 可以通过节点使用 slazure 吗?或者只有 C#。
  • @kkap Slazure 仅适用于 .NET 开发人员,抱歉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-08
  • 2019-11-16
  • 1970-01-01
  • 1970-01-01
  • 2014-02-07
相关资源
最近更新 更多