[Azure] C# + Microsoft.Azure.Cosmos.Table v1+ Azure Storage Table - TableBatchOperation 執行大量資料的方法(超過100筆)
前幾天寫了一篇文章 [Azure] C# + Microsoft.Azure.Cosmos.Table v1+ Azure Storage Table - 建立 Table,刪除 Table,建立(修改)資料,列出資料,刪除資料,刪除資料 by PartitionKey ,其中最後一個案例,刪除資料 by PartitionKey ,有一個小瑕疵,我在測試時候資料沒有超過 100 筆 沒有發現,但是測試資料量超過 100 後就出現 Exception 了。
錯誤訊息:
Unhandled exception. System.InvalidOperationException: The maximum number of operations allowed in one batch has been exceeded.
at Microsoft.Azure.Cosmos.Table.TableBatchOperation.Execute(CloudTableClient client, CloudTable table, TableRequestOptions requestOptions, OperationContext operationContext)
at Microsoft.Azure.Cosmos.Table.CloudTable.ExecuteBatch(TableBatchOperation batch, TableRequestOptions requestOptions, OperationContext operationContext)
今天,我們來試著解決這問題..
前置作業 首先你要 安裝 nuget https://www.nuget.org/packages/Microsoft.Azure.Cosmos.Table ,這邊我撰寫案例是用 .net core 3.1;在 Azure Portal 開一個 儲存體帳戶,並且在左側的存取金鑰中拿到 Connection String.
現在我在 Azure Table 上面有 1000 筆資料,一樣 PartitionKey 是 CLASSA ,我全部撈回來後要刪掉,其實這做法,就是我判斷撈回來的資料超過100筆的時候,我把它每100作為一群,然後在每群去刪除,簡單的說就是 雙層迴圈阿,沒有一個迴圈解決不了的問題,如果有 就兩個 ?
程式碼:
static IEnumerable<IEnumerable<T>> Split<T>(IEnumerable<T> source, int pageCount) | |
{ | |
return source | |
.Select((x, i) => new { Index = i, Value = x }) | |
.GroupBy(x => x.Index / pageCount) | |
.Select(x => x.Select(v => v.Value).ToList()) | |
.ToList(); | |
} | |
static void DeleteByPartitionKey() | |
{ | |
var tableClient = CloudStorageAccount.Parse(_ConnectionString).CreateCloudTableClient(new TableClientConfiguration()); | |
var table = tableClient.GetTableReference("table1"); | |
var queryAllRowKeysByPK = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", | |
QueryComparisons.Equal, "CLASSA")).Select(new[] { "RowKey" }); | |
//抓回所有 PartitionKey = CLASSA 的結果 | |
var entities = table.ExecuteQuery(queryAllRowKeysByPK); | |
// 因為TableBatchOperation 不能加入超過100 | |
//所以要分組 每100個為一組 | |
var split100Entities = Split(entities, 100); | |
foreach (var split100Entry in split100Entities) | |
{ | |
var batch = new TableBatchOperation(); | |
//將100加入到 TableBatchOperation 中 | |
foreach (var wannaDeleteData in split100Entry) | |
{ | |
batch.Add(TableOperation.Delete(wannaDeleteData)); | |
} | |
try | |
{ | |
table.ExecuteBatch(batch); | |
} | |
catch (Exception ex) | |
{ | |
Console.WriteLine("Error:" + ex.Message); | |
} | |
} | |
} | |
reference :
https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.cosmos.table.tablebatchoperation?view=azure-dotnet