views:

41

answers:

1

I have a Linq extension method to dynamically filter Linq queries using string values. For example: query.WhereHelper("columName", ">", 1). I could use many different filter operators like GreaterThan or NotEqual etc. but not "Like". There is no Expression.Like or Expression.StartsWith etc. How can I implement Like operator to my Expression tree? Here's my code:

public static IQueryable<T> WhereHelper<T>(this IQueryable<T> source, string columnName, object value, string filterType)
{
    ParameterExpression table = Expression.Parameter(typeof(T), "");
    Expression column = Expression.PropertyOrField(table, columnName);
    Expression valueExpression = Expression.Convert(Expression.Constant(value), column.Type);
    Expression where = null;

    switch (filterType)
    {
        case "<":
            where = Expression.LessThan(column, valueExpression);
            break;
        case "<=":
            where = Expression.LessThanOrEqual(column, valueExpression);
            break;
        case "=":
            where = Expression.Equal(column, valueExpression);
            break;
        case ">":
            where = Expression.GreaterThan(column, valueExpression;
            break;
        case ">=":
            where = Expression.GreaterThanOrEqual(column, valueExpression);
            break;
        case "<>":
            where = Expression.NotEqual(column, valueExpression);
            break;
    }

    Expression lambda = Expression.Lambda(where, new ParameterExpression[] { table });

    Type[] exprArgTypes = { source.ElementType };

    MethodCallExpression methodCall = Expression.Call(typeof(Queryable),
                                                      "Where",
                                                      exprArgTypes,
                                                      source.Expression,
                                                      lambda);

    return (IQueryable<T>)source.Provider.CreateQuery<T>(methodCall);
+3  A: 

You would use Expression.Call with the string.StartsWith, string.Contains, string.EndsWith etc methods. It is for the consuming code to translate it back to TSQL. Note that for LINQ-to-SQL there are also some additional helper functions here, but not with EF.

Marc Gravell
The "helper functions" I mean are [`SqlMethods`](http://msdn.microsoft.com/en-us/library/system.data.linq.sqlclient.sqlmethods.aspx) - in particular `Like()`
Marc Gravell
The comment about EF is incorrect. There is [EntityFunctions](http://msdn.microsoft.com/en-us/library/system.data.objects.entityfunctions.aspx) which is analagous to `SqlMethods` for L2S. However, functions such as `EndsWith` and `Contains` are natively supported in EF and don't require such helpers.
Craig Stuntz
@Craig thanks; I didn't know about that one.
Marc Gravell
I tried "Expression where = Expression.Call(typeof(string), "Contains", null, valueExpression)" and got ""No method 'Contains' exists on type 'System.String'." error. What am I doing wrong?
Armagan
@Armagan - it is an instance method; you need to pass in the left hand expression too.
Marc Gravell
Changed the expression to "Expression.Call(column, "Contains", null, valueExpression)" and it worked. Thanks a lot.
Armagan