我一直在尝试为Azure存储实体的删除操作实现DAO方法。使用TableOperation删除可以。在Azure存储中删除批处理操作
TableOperation deleteEntity = TableOperation.delete(entity);
但是,当我尝试使用批处理操作,它不被支持。
任何建议来解决这个问题是高度赞赏。
我一直在尝试为Azure存储实体的删除操作实现DAO方法。使用TableOperation删除可以。在Azure存储中删除批处理操作
TableOperation deleteEntity = TableOperation.delete(entity);
但是,当我尝试使用批处理操作,它不被支持。
任何建议来解决这个问题是高度赞赏。
但是,当我尝试使用批量操作,它不支持。
我认为你可以将你的项目按分区键进行分组,然后执行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);
}
});
嗨,谢谢你的回复。是的,我可以将项目按分区键进行分组。我用你的例子试了一下。但仍然给出了一个错误,指出java.lang.ClassCastException:java.util.ArrayList不能转换为com.microsoft.azure.storage.table.TableOperation \t at com.aepona.iotp.azure.reporting.AzureIotLocationDataDao.deleteLocationsForDevice(AzureIotLocationDataDao .java:188) –
你的代码是用java编写的吗?我的代码片段是由C#编写的。错误是关于类型转换异常,你可以尽力解决这个错误,或者你可以用你的代码片段更新你的问题,以便我们找到错误。 –
是的,它是用java编写的。以下是代码 –
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");
}
'ClassCastException'是由上述方法抛出的吗?你能找到特定的代码行吗? –
不,这是没有使用块操作的代码。以下是包含块操作的代码。对不起,没有提及
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();
}
}
从[CloudTable](https://azure.github.io/azure-sdk-for-java/com/microsoft/azure/storage/table/CloudTable.html),我们可以发现它支持'CloudTable.execute(TableBatchOperation批处理)',你需要改变你的代码来执行批处理操作,像这样'cloudTable.execute(batchOperation);'。 –
此外,一个[TableBatchOperation](https://azure.github.io/azure-sdk-for-java/com/microsoft/azure/storage/table/TableBatchOperation.html)最多可以包含100个单独的表操作,您可以将多个表操作添加到一个TableBatchOperation实例中,然后迭代List
工作!非常感谢 :) –
当你试图批量删除实体时,你碰到了什么错误?请注意批次中的实体应共享相同的分区密钥。 –
错误是'code' java.lang.ClassCastException。是的,我使用的是相同的分区键 –