如何从 Azure 存储 Table 中删除时间戳超过 1 天的所有实体?

How to delete all entities with a timestamp more than 1 day old from Azure Storage Table?

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

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

编辑:

根据给出的建议,我编写了以下代码。但是,它在我的 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

这是供选择 copy/reference 的任何人使用的最终工作代码。

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

}

您必须执行分区扫描才能执行此操作,因为实体仅在其 PartitionKey 和 RowKey 上建立索引。

在您发布的教程 link 中,查看 检索分区中的一系列实体 部分。获取要删除的实体后,您将执行 table 操作将其删除。

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

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

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

documentation 开始:

The Timestamp property is a DateTime value that is maintained on the server side to record the time an entity was last modified

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

如果你使用 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。