Linq: Group by multiple columns using Expression-tree syntax

anonymous-types c# expression-trees linq


I would like to change the following code so as to handle grouping of more than 1 property

private Expression<Func<ProfileResultView, string>> DynamicGroupBy(string propertyName)
    var parameterExp = Expression.Parameter(typeof(ProfileResultView), "x");
    var memberExp = Expression.PropertyOrField(parameterExp, propertyName);
    return Expression.Lambda<Func<ProfileResultView, string>>(memberExp, parameterExp);

so then this would be translated to

GroupBy(x => new { x.Column1, x.Column2 })

how can I write the anonymous type in the expression-tree syntax?

11/4/2015 2:08:30 PM

Popular Answer

If the type of the grouping key does not matter for you, you can create types dynamically and call the grouping based on those types:

public static Expression<Func<TSource, object>> DynamicGroupBy<TSource>
       (params string[] properties)
    var entityType = typeof(TSource);
    var props = properties.Select(x => entityType.GetProperty(x)).ToList();
    var source = Expression.Parameter(entityType, "x");

    // create x=> new myType{ prop1 = x.prop1,...}
    var newType = CreateNewType(props);
    var binding = props.Select(p => Expression.Bind(newType.GetField(p.Name), 
                  Expression.Property(source, p.Name))).ToList();
    var body = Expression.MemberInit(Expression.New(newType), binding);
    var selector = Expression.Lambda<Func<TSource, object>>(body, source);
   return selector;
public static Type CreateNewType(List<PropertyInfo> props)
   AssemblyName asmName = new AssemblyName("MyAsm");
   AssemblyBuilder dynamicAssembly = AssemblyBuilder
       .DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run);
   ModuleBuilder dynamicModule = dynamicAssembly.DefineDynamicModule("MyAsm");
   TypeBuilder dynamicAnonymousType = dynamicModule
       .DefineType("MyType", TypeAttributes.Public);

   foreach (var p in props)
       dynamicAnonymousType.DefineField(p.Name, p.PropertyType, FieldAttributes.Public);
   return dynamicAnonymousType.CreateType();

Note that the group key type is object.

12/20/2015 8:44:33 AM

Related Questions

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow