c# - Linq GroupBy Anonymous Type with Dynamic Properties -


this question has answer here:

i'm trying use linq group list<person>.

var grouped = personlist.groupby(x => new { x.forename, x.age })                         .select(x => new { description = x.key, count = x.count() }); 

how can make properties that'll grouped come variable?

var groupbyproperties = new string[] { "forename", "age" }; personlist.groupby(x => new { ............ })           .select(x => new { description = x.key, count = x.count() }); 

groupbyproperties come user input on webpage (<select multiple>).

i can't quite head around right syntax expandoobject or dynamic, , aren't sure if need use reflection here.

the person class might like:

public class person {     public string forename { get; set; }     public string surname { get; set; }     public int age { get; set; }     public string gender { get; set; } } 

the result passed through ui (a web page) json, datagrid generated. i'll using javascript loop through returned description object, , generate grid that.

with potehin143 pointing me towards scottgu's excellent linq dynamic query library, i've managed running.

i've ended nice one-liner (albeit bizarre syntax).

var fieldstogroupby = new string[] { "forename", "age" };  var grouped = personlist.groupby( "new ( "+fieldstogroupby.tocommaseparatedstring("it.")+" )", "it" )                  .select("new ( it.key description, it.count() count )");  response.data = (dynamic)grouped; 

tocommaseparatedstring() simple extension method change ["forename","age"] "it.forename, it.age".

the previous solution (below) wasn't returning data in quite format hoping. (it returning all data in groups, rather summary.) credit mitsu solution (blog posts here , here).

var groupbyproperties = new string[] { "forename", "age" }; var grouped = personlist.groupbymany(groupbyproperties); 

the linq dynamic query library post snippet from. groupbymany method:

public static ienumerable<groupresult> groupbymany<telement>(        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()); }  public static ienumerable<groupresult> groupbymany<telement>(     ienumerable<telement> elements,     params func<telement, object>[] groupselectors) {     if (groupselectors.length > 0)     {         var selector = groupselectors.first();          //reduce list recursively until 0         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; } 

Comments

Popular posts from this blog

Email notification in google apps script -

c++ - Difference between pre and post decrement in recursive function argument -

javascript - IE11 incompatibility with jQuery's 'readonly'? -