Linq: regrouper par plusieurs colonnes à l'aide de la syntaxe Expression-tree

anonymous-types c# expression-trees linq

Question

Je voudrais changer le code suivant afin de gérer le regroupement de plus d'une propriété

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

alors alors cela serait traduit à

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

Comment puis-je écrire le type anonyme dans la syntaxe de l'arbre d'expression?

Réponse populaire

Si le type de clé de regroupement n'a pas d'importance pour vous, vous pouvez créer des types de manière dynamique et appeler le groupe en fonction de ces 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();
}

Notez que le type de clé de groupe est object .




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi