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
精彩评论