c# - Linq GroupBy Anonymous Type with Dynamic Properties -
this question has answer here:
- linq grouping dynamically 5 answers
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
Post a Comment