Vlad
Vlad

Reputation: 2565

Dynamic lambda for Where method in linq

I am wondering how to pass a property of an object dynamically as a part of the lambda that will be used in the Where method of IQueryable.

Assume I have this code:

var list = new List<Item>();
...

var filtered = list.AsQueryable().Where(x => x.SomePropertyA.Contains(someStringValue));

My task is to make the last statement as a generic method and use a parameter:

IQueryable<Item> SomeMethod(Expression<Func<Item, string>> expr, string stringValue) {

     return list.AsQueryable().Where (???);
}

SomeMethod(x => x.SomePropertyA, someStringValue);
SomeMethod(x => x.SomePropertyB, someStringValue);

...

My guts tell me I will have to use Expressions class to call the Contains method of the string that is returned by the expr, but not sure of how to do this, as I am not very familiar with this...

Upvotes: 1

Views: 83

Answers (1)

max
max

Reputation: 34437

This method will create the required expression:

static Expression<Func<T, bool>> CreateContainsPredicate<T>(Expression<Func<T, string>> property, string value)
{
    return Expression.Lambda<Func<T, bool>>( // Where() wants this kind of expression
        Expression.Call(                     // we need to call method
            property.Body,                   // on instance returned by passed expression
            typeof(string).GetMethod("Contains", new [] { typeof(string) }), // call 'Contains()'
            Expression.Constant(value)),     // pass value to Contains() method
        property.Parameters);                // resulting expression has same parameters as input expression
}

Usage:

IQueryable<Item> SomeMethod(Expression<Func<Item, string>> expr, string stringValue) {
    return list.AsQueryable().Where(CreateContainsPredicate<Item>(expr, stringValue));
}

Upvotes: 1

Related Questions