diff --git a/src/AnimeFeedManager.Features/Infrastructure/TableStorage/TableUtils.cs b/src/AnimeFeedManager.Features/Infrastructure/TableStorage/TableUtils.cs index 5e23928b..6707d311 100644 --- a/src/AnimeFeedManager.Features/Infrastructure/TableStorage/TableUtils.cs +++ b/src/AnimeFeedManager.Features/Infrastructure/TableStorage/TableUtils.cs @@ -174,16 +174,22 @@ internal static async Task> BatchDelete(TableClient try { if (entities.IsEmpty) return unit; - var deleteEntitiesBatch = entities - .Select(entityToDelete => new TableTransactionAction(TableTransactionActionType.Delete, entityToDelete)) - .ToList(); - - const ushort limit = 99; - for (ushort i = 0; i < deleteEntitiesBatch.Count; i += limit) + // Create batches based on partition keys, as this is a restriction in azure tables + foreach (var groupedEntities in entities.GroupBy(e => e.PartitionKey)) { - _ = await tableClient.SubmitTransactionAsync(deleteEntitiesBatch.Skip(i).Take(limit), token) - .ConfigureAwait(false); + var deleteEntitiesBatch = groupedEntities + .Select(entityToDelete => + new TableTransactionAction(TableTransactionActionType.Delete, entityToDelete)) + .ToList(); + + const ushort limit = 99; + for (ushort i = 0; i < deleteEntitiesBatch.Count; i += limit) + { + _ = await tableClient.SubmitTransactionAsync(deleteEntitiesBatch.Skip(i).Take(limit), token) + .ConfigureAwait(false); + } } + return unit; } catch (Exception e) @@ -193,23 +199,31 @@ internal static async Task> BatchDelete(TableClient } internal static async Task> BatchAdd(TableClient tableClient, - IEnumerable entities, CancellationToken token, TableTransactionActionType actionType = TableTransactionActionType.UpsertMerge) where T : ITableEntity + IEnumerable entities, CancellationToken token, + TableTransactionActionType actionType = TableTransactionActionType.UpsertMerge) where T : ITableEntity { try { if (!entities.Any()) return unit; - // Create the batch. - var addEntitiesBatch = new List(); - addEntitiesBatch.AddRange( - entities.Select(tableEntity => - new TableTransactionAction(actionType, tableEntity))); - const ushort limit = 99; - for (ushort i = 0; i < addEntitiesBatch.Count; i += limit) + + // Create batches based on partition keys, as this is a restriction in azure tables + foreach (var groupedEntities in entities.GroupBy(e => e.PartitionKey)) { - _ = await tableClient.SubmitTransactionAsync(addEntitiesBatch.Skip(i).Take(limit), token) - .ConfigureAwait(false); + var addEntitiesBatch = new List(); + addEntitiesBatch.AddRange( + groupedEntities.Select(tableEntity => + new TableTransactionAction(actionType, tableEntity))); + const ushort limit = 99; + for (ushort i = 0; i < addEntitiesBatch.Count; i += limit) + { + _ = await tableClient.SubmitTransactionAsync(addEntitiesBatch.Skip(i).Take(limit), token) + .ConfigureAwait(false); + } } + // Create the batch. + + return unit; } catch (Exception e)