【问题标题】:Azure october 2012 sdk - how to delete a table entity without retrieving it first?Azure 2012 年 10 月 sdk - 如何删除表实体而不先检索它?
【发布时间】:2012-10-26 16:51:49
【问题描述】:

在以前的版本中,我们可以这样做来删除一个实体而不知道它是否存在。

svc = new TestContext();
item = new TestEntity("item2pk", "item2rk");
svc.AttachTo("TestTable", item, "*");
svc.DeleteObject(item);
svc.SaveChanges();

(source)

新的 TableOperations 没有这种语法。我必须使用这种旧方法还是有办法?我希望保持一致,因为现在我的所有代码都使用版本 2 的新类。

编辑:标题具有误导性

【问题讨论】:

    标签: c# .net azure azure-storage azure-table-storage


    【解决方案1】:

    你需要使用TableOperation.Delete:

    var storageAccount = CloudStorageAccount.DevelopmentStorageAccount;
    var table = storageAccount.CreateCloudTableClient()
                                .GetTableReference("tempTable");
    table.CreateIfNotExists();
    
    // Add item.
    table.Execute(TableOperation.Insert(new TableEntity("MyItems", "123")));
    
    // Load items.
    var items = table.ExecuteQuery(new TableQuery<TableEntity>());
    foreach (var item in items)
    {
        Console.WriteLine(item.PartitionKey + " - " + item.RowKey);
    }
    
    // Delete item (the ETAG is required here!).
    table.Execute(TableOperation.Delete(new TableEntity("MyItems", "123") { ETag = "*" }));
    

    删除仅适用于存在的实体。尽管旧客户端有ContinueOnError 选项,但它与Batch 操作(as explained here)不兼容。

    如果您不知道实体是否存在,那么获得成功批量删除的唯一方法是先添加它们(或者如果它们已经存在则替换它们):

    var ensureItemsBatch = new TableBatchOperation();
    ensureItemsBatch.InsertOrReplace(new MyEntity("MyItems", "123") { Active = false });
    ensureItemsBatch.InsertOrReplace(new MyEntity("MyItems", "456") { Active = false });
    ensureItemsBatch.InsertOrReplace(new MyEntity("MyItems", "789") { Active = false });
    table.ExecuteBatch(ensureItemsBatch);
    
    var deleteItemsBatch = new TableBatchOperation();
    deleteItemsBatch.Delete(new MyEntity("MyItems", "123") { ETag = "*" });
    deleteItemsBatch.Delete(new MyEntity("MyItems", "456") { ETag = "*" });
    deleteItemsBatch.Delete(new MyEntity("MyItems", "789") { ETag = "*" });
    table.ExecuteBatch(deleteItemsBatch);
    

    【讨论】:

    • 谢谢,但这不起作用,即使使用 * ETag。我得到 StorageException:“指定的资源不存在。”
    • 澄清:您的代码有效,但在我的情况下,该项目确实不存在。我怎样才能让它忽略它?
    • 澄清2:我不能只捕获异常,因为这实际上是在批处理操作中完成的。
    • 您不能删除不存在的实体。我会更新我的答案。
    【解决方案2】:

    我使用自己的方法来捕获实体不存在时发生的 StorageException。此外,它返回实体是否被删除为 bool。

    public bool DeleteTableEntity(string partitionKey, string rowKey)
    {
        try
        {
            _table.Execute(TableOperation.Delete(new TableEntity(partitionKey, rowKey) { ETag = "*" }));
            return true;
        }
        catch (StorageException e)
        {
            if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound)
                return false;
            throw;
        }
    }
    

    _table 成员变量的类型为 CloudTable (Microsoft.WindowsAzure.Storage.Table.CloudTable)。 对于此示例,我使用随 NuGet 一起安装的 Microsoft.WindowsAzure.Storage.dll v2.1.0.3 程序集。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多