c# - No method 'Contains' exists on type 'System.Data.Linq.DataQuery`1[System.Object]' -


i trying build contains expression.

private expression<func<t, bool>> contains<t>(string property, ienumerable<dynamic> values, t item) {     parameterexpression pe = expression.parameter(item.gettype(), "c");     expression columnnameproperty = expression.property(pe, property);     var somevaluecontain = expression.constant(values, values.gettype());     var convertexpression = expression.convert(columnnameproperty, typeof(guid));     expression expression = expression.call(somevaluecontain, "contains", new type[] { }, convertexpression);      return expression.lambda<func<t, bool>>(expression, pe); } 

at run time got exception.

"no method 'contains' exists on type 'system.data.linq.dataquery`1[system.object]'."

the soultion cast values parameter list

private expression<func<t, bool>> contains<t>(string property, ienumerable<dynamic> values, t item) {     parameterexpression pe = expression.parameter(item.gettype(), "c");     expression columnnameproperty = expression.property(pe, property);     guidvalues = values.cast<guid>().tolist();     var somevaluecontain = expression.constant(guidvalues, guidvalues.gettype());     var convertexpression = expression.convert(columnnameproperty, typeof(guid));     expression expression = expression.call(somevaluecontain, "contains", new type[] { }, convertexpression);      return expression.lambda<func<t, bool>>(expression, pe); } 

the problem values list more 10000 performance low , got exception

"the incoming request has many parameters. server supports maximum of 2100 parameters. reduce number of parameters , resend request."

i there way build dynamically lambda expression generate query

select * x id in (select id y) 

this syntactic sugar getting better of :)

the problem contains indeed not method on dataquery<t> - it's static method in system.linq.queryable. c# compiler handles via extension methods, that's c# compiler - it's not feature of il, it's feature of c#. when you're manipulating expression trees or emitting raw il, have handle yourself:

private expression<func<t, bool>> contains<t, v>  (string property, iqueryable<v> values, t item) {         parameterexpression pe = expression.parameter(item.gettype(), "c");         expression columnnameproperty = expression.property(pe, property);         var somevaluecontain = expression.constant(values, values.gettype());         var convertexpression = expression.convert(columnnameproperty, typeof(v));         expression expression =            expression.call           (             (              ((expression<func<bool>>)              (() => queryable.contains(default(iqueryable<v>), default(v)))             )             .body methodcallexpression).method,              somevaluecontain,              convertexpression           );          return expression.lambda<func<t, bool>>(expression, pe); } 

i'd avoid using dynamic in linq queries - way you're using it, it's no better having ienumerable<object>, , if want guid anyway, make generic :)

this method assumes whatever type of column convertible type of items in enumerable you're passing, of course, work type, not guid.

however, not solve second problem have - it's quite explicit. enumerable you're passing has way many items pass. unless linq provider has better way of passing values, you'll have resort splitting query multiple separate queries, each e.g. 1000 items, , joining results together. unless of course, guess right, , values you're passing in fact queryable - in case, code should work fine.

edit:

the best way i've found of getting proper methodinfo set of methods this:

public static methodinfo method<tr>(expression<func<tr>> expression) {     return (expression.body methodcallexpression).method; }  public static methodinfo method<t1, tr>(expression<func<t1, tr>> expression) {     return (expression.body methodcallexpression).method; } 

(autogenerated same way actual func<...> delegates are)

this allows simplifying getting method info this:

method((iqueryable<t> queryable, t item) => queryable.contains(item)) 

or alternatively (to avoid having generate possible overloads):

method(() => default(iqueryable<t>).contains(default(t))) 

Comments

Popular posts from this blog

Android : Making Listview full screen -

javascript - Parse JSON from the body of the POST -

javascript - Chrome Extension: Interacting with iframe embedded within popup -