I have a class called TestObject
with a Name
parameter.
I create a list and add 2 of these. I want to create a generic Where()
clause method for any IQueryable<T>
.
I've been playing around with Expressions but I don't really know what I'm doing.
I created this method with some hardcoded values for testing, I want it to do collection.Where(c => c.Name == "Boris")
:
public static IQueryable<T> Apply<T>(IQueryable<T> collection)
{
var parameterName = "Name";
var searchValue = "Boris";
var selectorParameter = Expression.Parameter(typeof(T), parameterName);
var searchTermExpression = Expression.Constant(searchValue);
var checkEqualsExpression = Expression.Call(selectorParameter, typeof(string).GetMethod("Equals"), searchTermExpression);
var methodCallExpression = Expression.Call(typeof(Queryable),
"Where",
new Type[] { collection.ElementType },
collection.Expression,
Expression.Lambda<Func<T, bool>>(checkEqualsExpression , ?????));
return collection.Provider.CreateQuery<T>(methodCallExpression);
}
I'm not sure what goes in ?????
or even if this is correct. Can anyone advise?
Here is an example of how to do it, with comments, it should clarify what you are doing wrong.
public static IQueryable<T> Apply<T>(IQueryable<T> collection) {
var propertyName = "Name";
var searchValue = "Boris";
// we have parameter "c"
var selectorParameter = Expression.Parameter(typeof(T), "c");
// constant "Boris"
var searchTermExpression = Expression.Constant(searchValue);
// "c.Name"
var selector = Expression.PropertyOrField(selectorParameter, propertyName);
// "c.Name == "Boris"
var equal = Expression.Equal(selector, searchTermExpression);
// c => c.Name == "Boris"
var where = Expression.Lambda<Func<T, bool>>(equal, selectorParameter);
return collection.Where(where);
}