2013-04-23 67 views
1

当在“foreach”循环中删除时,在Azure表中删除实体时,我还没有一致的结果。 PartitionKey是唯一的。在ForEach循环中删除Azure表实体的最佳做法

是否有最佳做法,人们可以推荐?

为了简洁,我省略了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似乎删除了大多数实体,但通常最后的实体不会删除。这是一个有效的实体。

+1

那么,你想要删除具有相同RowKey但不同的PartitionKey的实体吗?这有点奇怪,可能是缓慢和不完全删除的原因。 Azure存储无法高效地扫描所有的PartitionKey,因此您应该考虑熟知或修复PartitionKey,而不是RowKey。 http://www.windowsazure.com/en-us/develop/net/how-to-guides/table-services/#concepts – Pascal 2013-04-23 15:07:01

+0

谢谢你们的回应。在做了更多的研究后,我找到了解决我的问题的决议。请参阅以下[StackOverflow问题](http://stackoverflow.com/questions/7590383/error-deleting-from-azure-cloud-table-resourcenotfound)。 – user1219694 2013-04-24 04:28:52

回答

24

如果您已经知道实体的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); 

一句话:一个批量操作允许在必须共享相同的PartitionKey,所以你可能需要将实体分割成适当的批次批次最多100个实体为此工作。

相关问题