So, I'm trying to figure out Expression trees. I'm trying to add in a dynamic equals to a Queryable where T is one of several different tables. I'm first checking the table contains the field I want to filter on.
ParameterExpression param = Expression.Parameter(typeof(TSource), "x");
Expression conversionExpression = Expression.Convert(Expression.Property(param, _sourceProperty), typeof(TList));
Expression<Func<TSource, TList>> propertyExpression = Expression.Lambda<Func<TSource, TList>>(conversionExpression, param);
Expression<Func<TList, TList, bool>> methodExpression = (x, y) => x.Equals(y);
ReadOnlyCollection<ParameterExpression> parameters = propertyExpression.Parameters;
InvocationExpression getFieldPropertyExpression = Expression.Invoke(
propertyExpression,
parameters.Cast<Expression>());
MethodCallExpression methodBody = methodExpression.Body as MethodCallExpression;
MethodCallExpression methodCall = Expression.Call(methodBody.Method, Expression.Constant(equalTo), getFieldPropertyExpression);
Expression<Func<TSource, bool>> equalsStatement = Expression.Lambda<Func<TSource, bool>>(methodCall, parameters);
return source.Where(equalsStatement);
When I execute this, I get an issue with the MethodInfo in the Call statement. It tells me;
Static method requires null instance, non-static method requires non-null instance.
I'm no master of Expression trees, but I think I understand about 75% of what I'm doing here and know what I'm trying to achieve. The TList is a bad name right now, but I took this from an example that works to produce an In statement just fine.
I'm really looking for an explanation here so I can work through the code myself, or a solution with an explanation of what I was missing.
Edit:
Ok, so after a very frustrating afternoon and still not quite feeling like I understand what I'm looking at entirely, I think I have an answer.
ParameterExpression sourceObject = Expression.Parameter(typeof(TSource), "x");
Expression<Func<TSource, bool>> check = Expression.Lambda<Func<TSource, bool>>
(
Expression.Equal(
Expression.MakeMemberAccess(sourceObject, typeof(TSource).GetProperty(_sourceProperty)),
Expression.Constant(equalTo)
),
sourceObject
);
return source.Where(check);
Is anybody able to explain to me why the original just wasn't fit for what I was trying to do? I want to understand more about the actual process, but I feel I'm not picking it up as fast as I would like.