2017-07-06 53 views
0

我一直在嘗試爲Azure存儲實體的刪除操作實現DAO方法。使用TableOperation刪除可以。在Azure存儲中刪除批處理操作

TableOperation deleteEntity = TableOperation.delete(entity); 

但是,當我嘗試使用批處理操作,它不被支持。

任何建議來解決這個問題是高度讚賞。

+0

當你試圖批量刪除實體時,你碰到了什麼錯誤?請注意批次中的實體應共享相同的分區密鑰。 –

+0

錯誤是'code' java.lang.ClassCastException。是的,我使用的是相同的分區鍵 –

回答

0

但是,當我嘗試使用批量操作,它不支持。

我認爲你可以將你的項目按分區鍵進行分組,然後執行TableBatchOperation

在這裏,我寫了通過C#語言的一個輔助類爲實現這一目的,你可以參考一下吧:

public class TableBatchHelper<T> where T : ITableEntity 
{ 
    const int batchMaxSize = 100; 

    public static IEnumerable<TableBatchOperation> GetBatchesForDelete(IEnumerable<T> items) 
    { 
     var list = new List<TableBatchOperation>(); 
     var partitionGroups = items.GroupBy(arg => arg.PartitionKey).ToArray(); 
     foreach (var group in partitionGroups) 
     { 
      T[] groupList = group.ToArray(); 
      int offSet = batchMaxSize; 
      T[] entities = groupList.Take(offSet).ToArray(); 
      while (entities.Any()) 
      { 
       var tableBatchOperation = new TableBatchOperation(); 
       foreach (var entity in entities) 
       { 
        tableBatchOperation.Add(TableOperation.Delete(entity)); 
       } 
       list.Add(tableBatchOperation); 
       entities = groupList.Skip(offSet).Take(batchMaxSize).ToArray(); 
       offSet += batchMaxSize; 
      } 
     } 
     return list; 
    } 

    public static async Task BatchDeleteAsync(CloudTable table, IEnumerable<T> items) 
    { 
     var batches = GetBatchesForDelete(items); 
     await Task.WhenAll(batches.Select(table.ExecuteBatchAsync)); 
    } 
} 

然後,你可能在你執行批處理刪除如下:

await TableBatchHelper<ClassName>.BatchDeleteAsync(cloudTable,items); 

var batches = TableBatchHelper<ClassName>.GetBatchesForDelete(entities); 
Parallel.ForEach(batches, new ParallelOptions() 
{ 
    MaxDegreeOfParallelism = 5 
}, (batchOperation) => 
    { 
     try 
     { 
      table.ExecuteBatch(batchOperation); 
      Console.WriteLine("Writing {0} records", batchOperation.Count); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("ExecuteBatch throw a exception:" + ex.Message); 
     } 
    }); 
+0

嗨,謝謝你的回覆。是的,我可以將項目按分區鍵進行分組。我用你的例子試了一下。但仍然給出了一個錯誤,指出java.lang.ClassCastException:java.util.ArrayList不能轉換爲com.microsoft.azure.storage.table.TableOperation \t at com.aepona.iotp.azure.reporting.AzureIotLocationDataDao.deleteLocationsForDevice(AzureIotLocationDataDao .java:188) –

+0

你的代碼是用java編寫的嗎?我的代碼片段是由C#編寫的。錯誤是關於類型轉換異常,你可以盡力解決這個錯誤,或者你可以用你的代碼片段更新你的問題,以便我們找到錯誤。 –

+0

是的,它是用java編寫的。以下是代碼 –

0
public void deleteLocationsForDevice(String id) { 
    logger.info("Going to delete location data for Device [{}]", id); 

    // Create a filter condition where the partition key is deviceId. 
    String partitionFilter = TableQuery.generateFilterCondition(
      PARTITION_KEY, 
      TableQuery.QueryComparisons.EQUAL, 
      id); 

    // Specify a partition query, using partition key filter. 
    TableQuery<AzureLocationData> partitionQuery = 
      TableQuery.from(AzureLocationData.class) 
        .where(partitionFilter); 



    if (partitionQuery != null) { 
     for (AzureLocationData entity : cloudTable.execute(partitionQuery)) { 

      TableOperation deleteEntity = TableOperation.delete(entity); 
      try { 
       cloudTable.execute(deleteEntity); 
       logger.info("Successfully deleted location records with : " + entity.getPartitionKey()); 
      } catch (StorageException e) { 
       e.printStackTrace(); 
      } 

     } 

    } else { 
     logger.debug("No records to delete!"); 
    } 

    // throw new UnsupportedOperationException("AzureIotLocationDataDao Delete Operation not supported"); 
} 
+0

'ClassCastException'是由上述方法拋出的嗎?你能找到特定的代碼行嗎? –

0

不,這是沒有使用塊操作的代碼。以下是包含塊操作的代碼。對不起,沒有提及

TableBatchOperation batchOperation = new TableBatchOperation(); 
    List<TableBatchOperation> list = new ArrayList<>(); 

    if (partitionQuery != null) { 
     for (AzureLocationData entity : cloudTable.execute(partitionQuery)) { 

      batchOperation.add(TableOperation.delete(entity)); 
      list.add(batchOperation); //exception thrown line 
     } 
     try { 
      cloudTable.execute((TableOperation) batchOperation); 
     } catch (StorageException e) { 
      e.printStackTrace(); 
      } 
      } 
+0

從[CloudTable](https://azure.github.io/azure-sdk-for-java/com/microsoft/azure/storage/table/CloudTable.html),我們可以發現它支持'CloudTable.execute(TableBatchOperation批處理)',你需要改變你的代碼來執行批處理操作,像這樣'cloudTable.execute(batchOperation);'。 –

+0

此外,一個[TableBatchOperation](https://azure.github.io/azure-sdk-for-java/com/microsoft/azure/storage/table/TableBatchOperation.html)最多可以包含100個單獨的表操作,您可以將多個表操作添加到一個TableBatchOperation實例中,然後迭代List 並調用CloudTable.execute(TableBatchOperation批處理)。 –

+0

工作!非常感謝 :) –