LINQ 语句以 100 个块为单位执行 DynamicTableEntities 的嵌套列表
LINQ statements to do a nested list of DynamicTableEntities in chunks of 100
我正在尝试创建我可以从 Azure Table 存储中删除的 100 条记录的批次。我在此处找到了一篇关于高效创建批处理以删除 table 记录的好文章:https://blog.bitscry.com/2019/03/25/efficiently-deleting-rows-from-azure-table-storage/
并一直关注着这一点。我面临的问题与此博客中的示例不同 post 是我的删除将具有不同的分区键。因此,与其简单地将我的结果分成 100 个批次(如示例中那样),我首先需要将它们分成类似分区键的组,然后检查这些列表,如果计数大于则进一步细分它们100(因为 Azure 建议一次只分批处理 100 条记录,并且它们都需要相同的分区键)
让我说我对可枚举的 LINQ 和本博客中描述的非查询样式很糟糕 post 所以我有点迷茫。我已经写了一个小的解决方法,确实通过分区 ID 创建这些批次,并且代码可以删除它们,我只是没有处理可能有超过 100 行要根据分区键删除的可能性。因此,下面的代码仅用作示例,向您展示我是如何通过分区键拆分更新的。
List<string> partitionKeys = toDeleteEntities.Select(x => x.PartitionKey).Distinct().ToList();
List<List<DynamicTableEntity>> chunks = new List<List<DynamicTableEntity>>();
for (int i = 0; i < partitionKeys.Count; ++i)
{
var count = toDeleteEntities.Where(x => x.PartitionKey == partitionKeys[i]).Count();
//still need to figure how to split by groups of 100.
chunks.Add(toDeleteEntities.Distinct().Where(x=>x.PartitionKey == partitionKeys[i]).ToList());
}
我曾尝试在类似于此的 linq 函数中执行多个 groupby 语句
// Split into chunks of 100 for batching
List<List<TableEntity>> rowsChunked = tableQueryResult.Result.Select((x, index) => new { Index = index, Value = x })
.Where(x => x.Value != null)
.GroupBy(x => x.Index / 100)
.Select(x => x.Select(v => v.Value).ToList())
.ToList();
但是一旦我将第二组参数添加到分组依据(例如:x=>x.PartitionKey)然后我下面的 select 开始变成梨形。最终结果对象是包含 DyanmicTableEntities 和索引
的 LISTS 的 LIST
[0]
[0][Entity]
[1][Entity]
...
[99][Entity]
[1]
[0][Entity]
[1][Entity]
...
我希望这是有道理的,如果没有,请随时要求澄清。
提前致谢。
编辑澄清:
我的想法很简单,我想按分区键分组,并且在创建另一行相同分区键并添加其余行之前只取 100 行
谢谢,
您可以使用的一种有用的 LINQ 方法是 GroupBy(keySelector)。它基本上根据选择器将 collection 分成几组。所以在你的情况下,你可能想按 PartitionKey:
var partitionGroups = toDeleteEntities.GroupBy(d => d.PartitionKey);
当你遍历这个 collection 时,你会得到一个 IGrouping. Finally, to get the correct batch, you can use Skip(int count) and Take(int count)
foreach (var partitionGroup in partitionGroups)
{
var partitionKey = partitionGroup.Key;
int startPosition = 0;
int count = partitionGroup.Count();
while(count > 0)
{
int batchSize = count % maxBatchSize > 0 ? count % maxBatchSize : maxBatchSize;
var partitionBatch = partitionGroup.Skip(startPosition).Take(batchSize);
// process your batches here
chunks.Add(new List<DynamicTableEntry>(partitionBatch));
startPosition += batchSize;
count = count - batchSize;
}
}
我正在尝试创建我可以从 Azure Table 存储中删除的 100 条记录的批次。我在此处找到了一篇关于高效创建批处理以删除 table 记录的好文章:https://blog.bitscry.com/2019/03/25/efficiently-deleting-rows-from-azure-table-storage/
并一直关注着这一点。我面临的问题与此博客中的示例不同 post 是我的删除将具有不同的分区键。因此,与其简单地将我的结果分成 100 个批次(如示例中那样),我首先需要将它们分成类似分区键的组,然后检查这些列表,如果计数大于则进一步细分它们100(因为 Azure 建议一次只分批处理 100 条记录,并且它们都需要相同的分区键)
让我说我对可枚举的 LINQ 和本博客中描述的非查询样式很糟糕 post 所以我有点迷茫。我已经写了一个小的解决方法,确实通过分区 ID 创建这些批次,并且代码可以删除它们,我只是没有处理可能有超过 100 行要根据分区键删除的可能性。因此,下面的代码仅用作示例,向您展示我是如何通过分区键拆分更新的。
List<string> partitionKeys = toDeleteEntities.Select(x => x.PartitionKey).Distinct().ToList();
List<List<DynamicTableEntity>> chunks = new List<List<DynamicTableEntity>>();
for (int i = 0; i < partitionKeys.Count; ++i)
{
var count = toDeleteEntities.Where(x => x.PartitionKey == partitionKeys[i]).Count();
//still need to figure how to split by groups of 100.
chunks.Add(toDeleteEntities.Distinct().Where(x=>x.PartitionKey == partitionKeys[i]).ToList());
}
我曾尝试在类似于此的 linq 函数中执行多个 groupby 语句
// Split into chunks of 100 for batching
List<List<TableEntity>> rowsChunked = tableQueryResult.Result.Select((x, index) => new { Index = index, Value = x })
.Where(x => x.Value != null)
.GroupBy(x => x.Index / 100)
.Select(x => x.Select(v => v.Value).ToList())
.ToList();
但是一旦我将第二组参数添加到分组依据(例如:x=>x.PartitionKey)然后我下面的 select 开始变成梨形。最终结果对象是包含 DyanmicTableEntities 和索引
的 LISTS 的 LIST[0]
[0][Entity]
[1][Entity]
...
[99][Entity]
[1]
[0][Entity]
[1][Entity]
...
我希望这是有道理的,如果没有,请随时要求澄清。
提前致谢。
编辑澄清:
我的想法很简单,我想按分区键分组,并且在创建另一行相同分区键并添加其余行之前只取 100 行
谢谢,
您可以使用的一种有用的 LINQ 方法是 GroupBy(keySelector)。它基本上根据选择器将 collection 分成几组。所以在你的情况下,你可能想按 PartitionKey:
var partitionGroups = toDeleteEntities.GroupBy(d => d.PartitionKey);
当你遍历这个 collection 时,你会得到一个 IGrouping. Finally, to get the correct batch, you can use Skip(int count) and Take(int count)
foreach (var partitionGroup in partitionGroups)
{
var partitionKey = partitionGroup.Key;
int startPosition = 0;
int count = partitionGroup.Count();
while(count > 0)
{
int batchSize = count % maxBatchSize > 0 ? count % maxBatchSize : maxBatchSize;
var partitionBatch = partitionGroup.Skip(startPosition).Take(batchSize);
// process your batches here
chunks.Add(new List<DynamicTableEntry>(partitionBatch));
startPosition += batchSize;
count = count - batchSize;
}
}