c# - Generate Dynamic Linq query using outerIt -
i using microsoft's dynamic linq (system.linq.dynamic) library generate queries @ run time. has worked great me, 1 specific scenario.
simplified scenario - trying query claims have specific tags user has selected , balance greater number.
static void main(string[] args) { var claims = new list<claim>(); claims.add(new claim { balance = 100, tags = new list<string> { "blah", "blah blah" } }); claims.add(new claim { balance = 500, tags = new list<string> { "dummy tag", "dummy tag 1" } }); // tags searched var tags = new list<string> { "new", "blah" }; var parameters = new list<object>(); parameters.add(tags); var query = claims.asqueryable().where("tags.any(@0.contains(outerit)) , balance > 100", parameters.toarray()); } public class claim { public decimal? balance { get; set; } public list<string> tags { get; set; } }
this query throws error:
an unhandled exception of type 'system.linq.dynamic.parseexception' occurred in system.linq.dynamic.dll additional information: no property or field 'balance' exists in type 'string'
dynamic linq parser seems try find balance property on tag , not on claim object.
- i have tried play around outerit, innerit, it keywords in dynamic linq none of seems work.
- changing sequence works, that's not option me, since in real application filters, operators , patterns dynamic (configured end user).
- boxing conditions in brackets (), doesn't help.
- workaround - create simple contains condition every tag selected e.g. tags.contains("new") or tags.contains("blah") etc.. in real application results in complex / bad query each condition , kills performance.
i might missing or bug in library.
i appreciate if me this.
found a/the bug in parseaggregate... pushing of it
→outerit
, doesn't work if there multiple levels. code supposes it
, outerit
won't changed third party before being reset (technically code isn't reentrant). can try other variants of system.linq.dynamic
(there 2 or 3 variants out of there). variants have fixed it.
or can take code linked site , recompile inside code (in end "original" system.linq.dynamic single cs file) , can patch this:
expression parseaggregate(expression instance, type elementtype, string methodname, int errorpos) { // change starts here var originalit = it; var originalouterit = outerit; // change ends here outerit = it; parameterexpression innerit = expression.parameter(elementtype, elementtype.name); = innerit; expression[] args = parseargumentlist(); // change starts here = originalit; outerit = originalouterit; // change ends here methodbase signature; if (findmethod(typeof(ienumerablesignatures), methodname, false, args, out signature) != 1)
i've opened issue suggested bug fix in github of project.
Comments
Post a Comment