如何创建创建最多100个对象组的Linq表达式

时间:2010-11-29 13:25:55

标签: c# linq

我有一个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个客户。

4 个答案:

答案 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