开发者

How do I create a Linq expression that creates groups of max 100 objects

开发者 https://www.devze.com 2023-01-27 15:57 出处:网络
I have a LINQ expression that groups customers from an Azure Table Storage by partition. Because Azure only supports batch operations with max 100 entities at a time (and entities in a batch much hav

I have a LINQ expression that groups customers from an Azure Table Storage by partition.

Because Azure only supports batch operations with max 100 entities at a time (and entities in a batch much have the same PartitionKey), I need each group to contain a maximum 100 entities.

//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 => {...});

How do I complete my LINQ expression, so each group contains max 100 customers? That is... if the customers collection eg. has 142 customers with the same PartitionKey, i wa开发者_StackOverflow中文版nt to create two groups... one groups with 100 customers and one with 42 customers.


For LINQ to Objects:

yourCollection
   .Select((v, i) => new {Value = v, Index = i}) 
   .GroupBy(x => x.Index / 100)

Not sure if this works with Azure though...


There's nothing within "normal" LINQ to do this directly, but MoreLINQ has a Batch method which you may find useful:

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)

Note that in your case you'd probably want something like:

var groups = customers.GroupBy(c => c.PartitionKey).Batch(100, p => p.ToList());

so that the returned results are materialized immediately.

Of course, this is assuming you're using LINQ to Objects - if you're trying to partition via another LINQ provider, I'm not sure how you'd go about it.


This sounds like a job for .Skip and .Take, something like the following:

result = collection.Skip(100 * i).Take(100);

Where i is the page or group number you want to fetch.


This is my test applying "into" and "take" to group result:

        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();
            }
        }

Output:

1
3
5

2
4
6
0

精彩评论

暂无评论...
验证码 换一张
取 消