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
加载中,请稍侯......
精彩评论