We have an entity of type T1
which has a member of type T
.
something like this :
public class T1
{
public T Member{get;set;}
}
User can use our UI to give us a filter over T and we have translate it to an expression of a function that gets a T and returns bool (Expression<Func<T,bool>>)
I would like to know is it possible to convert this to an expression of a function that gets T1 and returns bool.
Actually I'd like to convert this :
(t=>t.Member1==someValue && t.Member2==someOtherValue);
to this :
(t1=>t1.Member.Member1==someValue && t1.Member.Member2==someOtherValue);
You can do it with a few way.
First and simplest: use Expression.Invoke
Expression<Func<T, bool>> exprT = t.Member1==someValue && t.Member2==someOtherValue
ParameterExpression p = Expression.Parameter(typeof(T1));
var expr = Expression.Invoke(expr, Expression.PropertyOrField(p, "Member"));
Expression<Func<T1, bool>> exprT1 = Expression.Lambda<Func<T1, bool>>(expr, p);
but in this case you get not
t1 => (t=>(t.Member1==someValue && t.Member2==someOtherValue))(t1.Member),
instead of
(t1=>t1.Member.Member1==someValue && t1.Member.Member2==someOtherValue);
For replacing you can use ExpressionVisitor class like
class V : ExpressionVisitor
{
public ParameterExpression Parameter { get; private set; }
Expression m;
public V(Type parameterType, string member)
{
Parameter = Expression.Parameter(parameterType);
this.m = Expression.PropertyOrField(Parameter, member);
}
protected override Expression VisitParameter(ParameterExpression node)
{
if (node.Type == m.Type)
{
return m;
}
return base.VisitParameter(node);
}
}
and use it
var v = new V(typeof(T1), "Member");
var exprT1 = Expression.Lambda<Func<T1, bool>>(v.Visit(exprT.Body), v.Parameter);