Reputation: 80
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
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