Shawn asked me in my last post about GroupByMany how to use it dynamically.
The answer is not easy. So here is a new post to answer to this interesting question.
First you must learn a few things about being dynamic with linq.There is a very good sample from the C# team (actually we can consider it as a library provided as a sample). ScottGu has post about it here: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx.
One of the power of linq is to be checked at compile-time. You must be aware that using this kind of solution may raise some exceptions at runtime.
Now I have added the Dynamic.cs file to my project and I can use a very useful method: DynamicExpression.ParseLambda.
Here is a new GroupByMany extension method which accepts a list of strings instead of delegates to define all the groupings.The goal is to call the first GroupByMany method. To do this we have to go from a single string defining the name of a property in the TElement class to a Func<TElement, object>.We could do this building the expression manually but DynamicExpression.ParseLambda will do it in just a single line.
public static class MyEnumerableExtensions { public static IEnumerable<GroupResult> GroupByMany<TElement>( this IEnumerable<TElement> elements, params string[] groupSelectors) { var selectors = new List<Func<TElement, object>>(groupSelectors.Length); foreach (var selector in groupSelectors) { LambdaExpression l = DynamicExpression.ParseLambda( typeof(TElement), typeof(object), selector); selectors.Add((Func<TElement, object>) l.Compile()); } return elements.GroupByMany(selectors.ToArray()); } ...
DataContext = customers.GroupByMany("Country", "City");
DataContext = customers.GroupByMany(c => c.Country, c => c.City);