How to convert a ExpressionTree of form
Expression<Func<POCO1, bool>> exp = p => p.Age > 50;
to
Expression<Func<POCO2, bool>> exp2 = p => p.Age > 50;
where POCO1 and POCO2 are C# objects and both have Int32 Age property
When you want to have a richer interaction, you need to use Expression Trees. Expression Trees represent code as a structure that you can examine, modify, or execute. These tools give you the power to manipulate code during run time. You can write code that examines running algorithms, or injects new capabilities.
You can compile and run code represented by expression trees. This enables dynamic modification of executable code, the execution of LINQ queries in various databases, and the creation of dynamic queries. For more information about expression trees in LINQ, see How to use expression trees to build dynamic queries (C#).
The ExpressionVisitor enables the visitor pattern for Expression 's.
well, you can make custom expression visitor that will replace parameter references and patch member access expressions
class Converter<TTo>
{
class ConversionVisitor : ExpressionVisitor
{
private readonly ParameterExpression newParameter;
private readonly ParameterExpression oldParameter;
public ConversionVisitor(ParameterExpression newParameter, ParameterExpression oldParameter)
{
this.newParameter = newParameter;
this.oldParameter = oldParameter;
}
protected override Expression VisitParameter(ParameterExpression node)
{
return newParameter; // replace all old param references with new ones
}
protected override Expression VisitMember(MemberExpression node)
{
if (node.Expression != oldParameter) // if instance is not old parameter - do nothing
return base.VisitMember(node);
var newObj = Visit(node.Expression);
var newMember = newParameter.Type.GetMember(node.Member.Name).First();
return Expression.MakeMemberAccess(newObj, newMember);
}
}
public static Expression<Func<TTo, TR>> Convert<TFrom, TR>(
Expression<Func<TFrom, TR>> e
)
{
var oldParameter = e.Parameters[0];
var newParameter = Expression.Parameter(typeof(TTo), oldParameter.Name);
var converter = new ConversionVisitor(newParameter, oldParameter);
var newBody = converter.Visit(e.Body);
return Expression.Lambda<Func<TTo, TR>>(newBody, newParameter);
}
}
class A
{
public int Value { get; set; }
}
class B
{
public int Value { get; set; }
}
Expression<Func<A, int>> f = x => x.Value;
var f2 = Converter<B>.Convert(f);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With