linq - Dynamically Adding a GroupBy to a Lambda Expression -
ok, i'll admit don't entirely "get" lambda expressions , linq expression trees yet; lot of i'm doing cutting , pasting , seeing works. i've looked on lots of documentation, still haven't found "aha" moment yet.
with being said...
i'm attempting dynamically add groupby expression linq expression. followed question here: need creating linq.expression enumerable.groupby
and tried implement saw there.
first off, i've got entity classes database, , table calledobjcurlocviewnormalized
i've got method initial call,
public iqueryable<objcurlocviewnormalized> getlocations() { iqueryable<objcurlocviewnormalized> res = (from loc in tms.objcurlocviewnormalized select loc); return res; }
so can call:
iqueryable<metamericanlinqdatamodel.objcurlocviewnormalized> locations = american.getlocations();
no problem far.
now, want group arbitrary column, call this:
var grouped = locations.addgroupby(childlocationfieldname);
right now, have method :
static public system.linq.iqueryable<system.linq.igrouping<string, tresult>> addgroupby<tresult>(this iqueryable<tresult> query, string columnname) { var providertype = query.provider.gettype(); // find specific type parameter (the t in iqueryable<t>) var iqueryablet = providertype.findinterfaces((ty, obj) => ty.isgenerictype && ty.getgenerictypedefinition() == typeof(iqueryable<>), null).firstordefault(); var tabletype = iqueryablet.getgenericarguments()[0]; var tablename = tabletype.name; var data = expression.parameter(iqueryablet, "query"); var arg = expression.parameter(tabletype, tablename); var nameproperty = expression.propertyorfield(arg, columnname); var lambda = expression.lambda<func<tresult, string>>(nameproperty, arg); var expression = expression.call(typeof(enumerable), "groupby", new type[] { tabletype, typeof(string) }, data, lambda); var predicate = expression.lambda<func<tresult, string>>(expression, arg); // line produces error describe below var result = query.groupby(predicate).asqueryable(); return result; }
all compiles ok, when run it, error:
system.argumentexception: expression of type 'system.collections.generic.ienumerable`1[system.linq.igrouping`2[system.string,metamericanlinqdatamodel.objcurlocviewnormalized]]' cannot used return type 'system.string'
and error comes line:
var predicate = expression.lambda<func<tresult, string>>(expression, arg);
i'm copying , adapting code successful work did in dynamically added clauses expression. i'm sort of stabbing in dark here.
if out there can shed light on this, posting complete working code , doing thinking me great :), if lay out why wrong, or how wrap head around these concepts, great. if can point documentation can bridge gap between basics of lambda expressions, , building dynamic expression trees, great. there's big holes in knowledge, think information useful others.
thanks time, , of course if find answer elsewhere, i'll post here.
thanks again.
don
the solution should pretty simple:
public static iqueryable<igrouping<tcolumn, t>> dynamicgroupby<t, tcolumn>( iqueryable<t> source, string column) { propertyinfo columnproperty = typeof(t).getproperty(column); var sourceparm = expression.parameter(typeof(t), "x"); var propertyreference = expression.property(sourceparm, columnproperty); var groupbyselector = expression.lambda<func<t, tcolumn>>(propertyreference, sourceparm); return source.groupby(groupbyselector); }
assuming sample class this:
public class testclass { public string testproperty { get; set; } }
you invoke this:
var list = new list<testclass>(); var queryable = list.asqueryable(); dynamicgroupby<testclass, string>(queryable, "testproperty");
Comments
Post a Comment