Kibner
Kibner

Reputation: 80

Can't use dynamic delegate parameter in lambda of expression tree

I am trying to apply a simple "Where" clause on a dynamically selected table. However, the table field the clause will be applied to is also dynamic and I can't figure out how to make that part work. Getting the dynamic table works correctly.

using (var context = new DBEntities())
{
    var type = context.GetType();
    var tableProperty = type.GetProperty("tableName");
    var tableGet = tableProperty.GetMethod;
    var tableContent = tableGet.Invoke(context, null);
    var tableQuery = (IQueryable)tableContent;
    var tableType = tableQuery.ElementType;

    var pe = Expression.Parameter(tableType, "tableType");
    var left = Expression.PropertyOrField(pe, "fieldName");
    var right = Expression.Constant("fieldValue");
    var predicateBody = Expression.Equal(left, right);

    var whereCallExpression = Expression.Call(typeof(Queryable), "Where", new[] { tableType },
        tableQuery.Expression, Expression.Lambda<Func<tableType, bool>>(predicateBody, pe));

    IQueryable<string> results = tableQuery.Provider.CreateQuery<string>(whereCallExpression);
}

This block of code will not compile because of Expression.Lambda<Func<tableType, bool>>(predicateBody, pe). If I hard-code types for the Expression-related code, this sample runs and returns the expected results.

Upvotes: 2

Views: 309

Answers (1)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726569

The code does not compile because tableType, a variable of type System.Type, cannot be used as a type parameter of a generic function.

However, you should be able to make this compile and run by replacing a call to generic Lambda<Func<...>> with a call to non-generic Lambda:

var whereCallExpression = Expression.Call(typeof(Queryable), "Where", new[] { tableType },
    tableQuery.Expression, Expression.Lambda(predicateBody, pe));

Upvotes: 1

Related Questions