当在“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似乎删除了大多数实体,但通常最后一个实体不会删除。这是一个有效的实体。
答案 0 :(得分:28)
如果您已经知道实体的PartitionKey和RowKey,则不必先加载它。最快的方法是直接使用CloudTable和DynamicTableEntity,如下所示:
var cloudTable = cloudTableClient.GetTableReference("TheTable");
var entity = new DynamicTableEntity("ThePartitionKey", "TheRowKey");
entity.ETag = "*";
cloudTable.Execute(TableOperation.Delete(entity));
如果要删除不了解RowKeys的实体集合,则需要先加载实体并使用Batch Operation删除实体。此外,您不需要加载实体的所有属性,我们只需要知道RowKey,这样我们就可以再次使用与上面相同的技术。为此我们使用Projection Query
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,因此您可能需要将实体拆分为适当的批次为了这个工作。