0

I have a series of objects that all have a similar property that is a List of the Ids of the groups to which they belong (many parents per child).

I'm having trouble programatically implementing the Linq Expression necessary to make this filter work correctly.

This is what I have so far:

IQueryable result = null;

   if (!string.IsNullOrWhiteSpace(this.ddlRouteNames.SelectedValue))
   {
      ConstantExpression ce = Expression.Constant(int.Parse(this.ddlRouteNames.SelectedValue));
      ParameterExpression pe = Expression.Parameter(source.ElementType);
      MemberExpression me = Expression.Property(pe, this.Column.Name);
      MethodCallExpression mce = Expression.Call(typeof(List<int>), "Contains", new[] { typeof(int) }, me, ce);

      result = source.Provider.CreateQuery(mce);
   }

return result;

I'm getting an exception when trying to create my MethodCallExpression:

No method 'Contains' exists on type 'System.Collections.Generic.List`1[System.Int32]'.

Any pointers on where to begin?

Sonny Boy
  • 7,848
  • 18
  • 76
  • 104

2 Answers2

0

The Type in the method signature you've used:

public static MethodCallExpression Call(Type type, 
                                        string methodName, 
                                        Type[] typeArguments, 
                                        params Expression[] arguments);

specifies the type that contains the specific static method.

You need the type instance for this method to be available - an example (related to your comment):

var par = Expression.Parameter(typeof(int), "par");            
var inst = Expression.Parameter(typeof(List<int>), "inst");
var body = Expression.Call(inst, typeof(List<int>).GetMethod("Contains"), par);
var exp = Expression.Lambda(body, inst, par);
var deleg = exp.Compile();

var lst = new List<int>() { 1, 2, 3, 4, 5 };
var exists = deleg.DynamicInvoke(lst, 3);
jwaliszko
  • 16,942
  • 22
  • 92
  • 158
  • Thanks. Is there something similar I can use that will achieve the desired results? I'm essentially trying to write an expression that will see if the selected Id appears in this object's List of Ids. – Sonny Boy May 07 '13 at 15:46
0

Your method call isn't correct, to call the non-static method you need to provide instance that contains the method. Here's example of Contains method call:

var list = new List<int> {1};
//Target for invoke method
var target = Expression.Constant(list);
var methodCallExpression = Expression.Call(target, typeof(List<int>).GetMethod("Contains"), Expression.Constant(1));

If in your code me it's a member that contains List the code will be look like this:

Expression.Call(me, typeof(List<int>).GetMethod("Contains"), ce);
Vyacheslav Volkov
  • 4,592
  • 1
  • 20
  • 20
  • Getting closer... The MethodCallExpression portion seems to work correctly, now, but when I try to use the IQueryable source to create the query, I get this exception: "Argument expression does not implement System.Linq.IQueryable`1[System.Boolean]." – Sonny Boy May 07 '13 at 15:59
  • What type of `source` variable? – Vyacheslav Volkov May 07 '13 at 16:05
  • source is an IQueryable that's passed into the GetQueryable method, which is overridden from the inheritance from QueryableFilterUserControl. – Sonny Boy May 07 '13 at 17:37