Search code examples
c#linqlambdaexpression-trees

Convert List.Contains to Expression Tree


Related To:

Create a Lambda Expression With 3 conditions

Convert Contains To Expression Tree

In the following of my previous question I faced with this query that I want to write Expression Tree version:

List<byte?> lst = new List<byte?>{1,2};
from a in myTbl
where a.Age = 20 && lst.Contains(a.Status)
select a

I write this code:

List<byte?> lst = new List<byte?>{1,2};
var param = Expression.Parameter(typeof(T), "o");
var body = Expression.AndAlso(
               Expression.Equal(
                    Expression.PropertyOrField(param, "Age"),
                    Expression.Constant(20)
               ),
               Expression.Call(Expression.PropertyOrField(param, "Status"),
                                   "Contains",
                                   Type.EmptyTypes, 
                                   Expression.Constant(lst)));

var lambda = Expression.Lambda<Func<T, bool>>(body, param);
return lambda;

and I get the error:

"No method 'Contains' exists on type 'System.Nullable`1[System.Byte]'."

Please help me to find the problem.

Thanks


Solution

  • The problem is that you have switched two arguments to Expression.Call, your code is trying to create the nonsensical expression o.Status.Contains(lst).

    You need to switch the two arguments around:

    Expression.Call(Expression.Constant(lst),
        "Contains",
        Type.EmptyTypes, 
        Expression.PropertyOrField(param, "Status"))
    

    This is assuming that the LINQ provider you're using understands List<T>.Contains(). If you need Enumerable.Contains(), then have a look at Ivan Stoev's answer.