2016-02-11 1 views
0

Je dois créer un arbre d'expressions dynamique pour GroupBy. Tout ce que je veux accomplir est comme ça.Création d'un arbre d'expressions de sélecteur GroupBy dynamique avec plusieurs propriétés

var NestedGrouped = listOfPerson.GroupByMany(x => x.Name,x=>x.Age).ToList(); 

Ma personne est comme classe: -

class Person 
{ 
public string Name{ get; set; } 
public int Age{ get; set; } 
public float Salary{ get; set; } 
} 
public class GroupResult 
{ 
     public object Key { get; set; } 
     public int Count { get; set; } 
     public IEnumerable Items { get; set; } 
     public IEnumerable<GroupResult> SubGroups { get; set; } 
     public override string ToString() 
     { return string.Format("{0} ({1})", Key, Count); } 
} 
public static class MyEnumerableExtensions 
{ 
     public static IEnumerable<GroupResult> GroupByMany<TElement>(
      this IEnumerable<TElement> elements, 
      params Func<TElement, object>[] groupSelectors) 
     { 
      if (groupSelectors.Length > 0) 
      { 
       var selector = groupSelectors.First(); 

       //reduce the list recursively until zero 
       var nextSelectors = groupSelectors.Skip(1).ToArray(); 
       return 
        elements.GroupBy(selector).Select(
         g => new GroupResult 
         { 
          Key = g.Key, 
          Count = g.Count(), 
          Items = g, 
          SubGroups = g.GroupByMany(nextSelectors) 
         }); 
      } 
      else 
       return null; 
     } 
    } 

Pour propriété unique Je suis en mesure de construire l'expression, mais je veux faire GROUPBY avec plusieurs colonnes comme indiqué ci-dessus. POUR LA PROPRIETE UNIQUE: -

ParameterExpression parameter = Expression.Parameter(typeof(Person), "lambdaKey"); 
      var menuProperty = Expression.PropertyOrField(parameter, "Name"); 
      var lambda = Expression.Lambda<Func<Person, string>>(menuProperty, parameter); 
      var selector = lambda.Compile(); 
      var result = P1.GroupByMany(selector);// P1 is list of PERSON 

Comment ajouter plusieurs colonnes dans l'arbre d'expression (par exemple (x => x.Name, x => x.Age)).
S'il vous plaît, aidez-nous. Merci d'avance.

+0

Ce qui est vraiment votre question? Il n'y a pas de colonnes multiples dans votre échantillon, mais une liste (tableau) de colonnes simples. –

+0

@IvanStoev Je veux générer dynamiquement l'arbre d'expression pour la liste des colonnes que je peux passer dans GroupByMany. – Pranav

+1

Il y a ** no ** arbre d'expression ** pour la liste des colonnes ** dans votre échantillon. De la même manière que vous construisez pour une seule propriété, vous pouvez allouer array et remplir chaque élément, puis passer le tableau à GroupByMany. 'params Func [] groupSelectors' est ** un tableau d'expressions **, pas une seule expression, n'est-ce pas? –

Répondre

1

GroupByMany() accepte un tableau de délégués, un délégué pour chaque clé. Donc, ce dont vous avez besoin est de créer et de compiler une expression séparée pour chaque clé.

Le code pourrait ressembler à:

private static Func<TElement, object> CreateSelector<TElement>(string key) 
{ 
    var parameter = Expression.Parameter(typeof(TElement), "lambdaKey"); 
    var property = Expression.PropertyOrField(parameter, key); 
    var lambda = Expression.Lambda<Func<TElement, string>>(property, parameter); 
    return lambda.Compile(); 
} 

public static IEnumerable<GroupResult> GroupByMany<TElement>(
    this IEnumerable<TElement> elements, 
    params string[] groupKeys) 
{ 
    return elements.GroupByMany(groupKeys.Select(CreateSelector<TElement>).ToArray()); 
} 
+0

@downvoter Vous voulez expliquer ce que vous pensez être faux avec cette réponse? – svick