5

当删除发生在“foreach”循环中时,删除 Azure 表中的实体时,我没有得到一致的结果。PartitionKey 是唯一的。

是否有人们可以推荐的最佳实践?

为简洁起见,我省略了 Try..Catch 语句。

假设:

var context = new FooContext(_storageAccount);

        var query = (from e in context.TableBar
                                where e.RowKey == rowKey
                                select e).AsTableServiceQuery();

方法#1

                foreach (var entity in query.Execute())
            {
                    // delete each entity
                    context.DeleteObject(entity);
                    context.SaveChanges();
            }

方法#2

            foreach (var entity in query.Execute())
            {
                    // delete each entity
                    context.DeleteObject(entity);
            }
            context.SaveChanges();

方法#3

            var bars = query.Execute();
            foreach (var bar in bars)
                context.DeleteObject(bar);
            context.SaveChanges();

方法 #1 似乎删除了大多数实体,但通常最后一个实体不会删除。这是一个有效的实体。

4

1 回答 1

35

如果您已经知道实体的 PartitionKey 和 RowKey,则不必先加载它。最快的方法是直接使用 CloudTable 和这样的DynamicTableEntity

var cloudTable = cloudTableClient.GetTableReference("TheTable");

var entity = new DynamicTableEntity(partitionKey, rowKey) { ETag = "*" };

cloudTable.Execute(TableOperation.Delete(entity));

如果要删除不知道 RowKeys 的实体集合,则需要先加载实体并使用批处理操作来删除实体。此外,您不需要加载实体的所有属性,我们只需要知道 RowKey,这样我们就可以再次使用与上述相同的技术。为此,我们使用投影查询

var batchOperation = new TableBatchOperation();

// We need to pass at least one property to project or else 
// all properties will be fetch in the operation
var projectionQuery = new TableQuery<DynamicTableEntity>()
    .Where(TableQuery.GenerateFilterCondition("PartitionKey", 
        QueryComparisons.Equal, "ThePartitionKey"))
    .Select(new string[] { "RowKey" });

foreach (var e in table.ExecuteQuery(projectionQuery))
    batchOperation.Delete(e);

table.ExecuteBatch(batchOperation);

提醒一句批处理操作最多允许批处理中的 100 个实体,它们必须共享相同的 PartitionKey,因此您可能需要将实体拆分为适当的批处理才能工作。

于 2013-04-23T15:56:20.810 回答