我有一个LINQ表达式,可以按分区从Azure表存储中对客户进行分组。
由于Azure仅支持一次最多100个实体的批处理操作(并且批处理中的实体具有相同的PartitionKey),因此我需要每个组包含最多100个实体。
//How to complete this LINQ expression
var groups = customers.GroupBy(c => c.PartitionKey)....;
//Do some Azure table storage magic in parallel
Parallel.ForEach(groups , customersInGroup => {...});
如何完成LINQ表达式,因此每组最多包含100个客户?那就是...如果客户收集,例如。有142个客户使用相同的PartitionKey,我想创建两个组...一个组有100个客户,一个有42个客户。
答案 0 :(得分:9)
对于LINQ to Objects:
yourCollection
.Select((v, i) => new {Value = v, Index = i})
.GroupBy(x => x.Index / 100)
不确定这是否适用于Azure,但是......
答案 1 :(得分:4)
“正常”LINQ中没有任何内容可以直接执行此操作,但MoreLINQ有一个Batch
方法,您可能会发现它很有用:
public static IEnumerable<TResult> Batch<TSource, TResult>
(this IEnumerable<TSource> source, int size,
Func<IEnumerable<TSource>, TResult> resultSelector)
public static IEnumerable<IEnumerable<TSource>> Batch<TSource>
(this IEnumerable<TSource> source, int size)
请注意,在您的情况下,您可能需要以下内容:
var groups = customers.GroupBy(c => c.PartitionKey).Batch(100, p => p.ToList());
以便立即实现返回的结果。
当然,假设你正在使用LINQ to Objects - 如果你试图通过另一个LINQ提供程序进行分区,我不确定你是怎么做的。
答案 2 :(得分:0)
这听起来像是.Skip
和.Take
的工作,如下所示:
result = collection.Skip(100 * i).Take(100);
i
是您要获取的页面或组号。
答案 3 :(得分:0)
这是我的测试应用“进入”和“接受”分组结果:
static void Main(string[] args) { int[] numbers = new int[] { 1,2,3,4,5,6,7,8,9,0 }; var result = from n in numbers group n by n%2 into group_numbers select new { short_group = group_numbers.Take(3) }; foreach(var v in result) { foreach (var v1 in v.short_group) { Console.WriteLine(v1.ToString()); } Console.WriteLine(); } }
输出:
1 3 5 2 4 6