0

I'm trying to build an expression that must create query of type WHERE IN () For IN I must check if value exist in a list, so my expression looks like:

long loKey = 2;
List<long> loKeys = new List<long>();
loKeys.Add(loKey);

ParameterExpression parameter = Expression.Parameter(type, "t");
var constantExpression = Expression.Constant((List<long>)loKeys, typeof(List<long>));
var lambda = Expression.Lambda(
    typeof(Func<,>).MakeGenericType(type, typeof(bool)),
    Expression.Equal(
        Expression.Property(parameter, "ID"),
        constantExpression
    ),
    parameter
);
resultQuery = resultQuery.Provider.CreateQuery(
    Expression.Call(
        typeof(Queryable), 
        "Where",
        new Type[] { type },
        resultQuery.Expression,
        lambda
    ) 
);

So the idea is that field ID must exist in list loKeys, but I'm getting an error:

Additional information: The binary operator Equal is not defined for the types 'System.Int64' and 'System.Collections.Generic.List`1[System.Int64]'.

On Expression.Lambda -> MakeGenericType

2
  • Why don't use something like query.Where(entity => keysEnumerable.Contains(entity.Id)), where keysEnumerable is IEnumerable<PrimaryKeyType>? Commented Mar 28, 2016 at 6:16
  • Because my query doesnt have type , so i cant use .Where Commented Mar 28, 2016 at 6:47

2 Answers 2

3

So you are trying to build something like this:

t => loKeys.Contains(t.ID)

The only thing you need to consider is that actually Contains is a static extension method defined in Enumerable class:

var lambda = Expression.Lambda(
    Expression.Call(
        typeof(Enumerable), 
        "Contains", 
        new[] { typeof(long) },
        Expression.Constant(loKeys),
        Expression.Property(parameter, "ID")
    ),
    parameter
);
Sign up to request clarification or add additional context in comments.

Comments

1

I think it the exception is thrown because of the part: Expression.Equal( Expression.Property(parameter, "ID"), constantExpression ), In which you're comparing the constantExpressions, which is a generic list, with a parameter of type long (i guess, doesn't say what type the parameter is), maybe instead of Equals you should use Method call for "Contains" and see if the parameter is in the list (like Dennis suggested).

2 Comments

Yes ,yes i thing about the same , but Expression doesn`t have method Contains .. so the real question is what method can be used instead of Equal ?
@HarryBirimirski if type is always ICollection, you can use Expression.Call and pass it ICollection.Contains() as methodInfo

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.