I am having a problem with converting a string to property.
Example of what do I have:
Expression<Func<string, bool>> expression = (a => a == "Hello");
What do I want:
Expression<Func<Entity, bool>> expression = (a => a.Name == "Hello");
However, I need the mentioned method to do the following as well:
Expression<Func<string, bool>> expression = (a => "Hello" == a);
=>
Expression<Func<Entity, bool>> expression = (a => "Hello" == a.Name);
What I think might work, but I am unable to do it:
- I think that a visitor could be a way how to properly do this. However, I am not sure how to properly handle it.
CodePudding user response:
You need to create new lambda expression where parameter has type Entity
and body is a body of original expression where string parameter replaced by accessor to Name property. ExpressionVisitor is a right tool to do such replacement
// parameter for new lambda
var p = Expression.Parameter(typeof(Entity), "p");
// Expression for p.Name
var exprProp = Expression.Property(p, nameof(Entity.Name));
// replace parameter in original expression
var visitor = new ReplaceParamVisitor(expression.Parameters[0], exprProp);
var exprNewBody = visitor.Visit(expression.Body);
// create new lambda
var lambda = Expression.Lambda<Func<Entity, bool>>(exprNewBody, p);
Visitor:
public class ReplaceParamVisitor: ExpressionVisitor
{
private readonly ParameterExpression param;
private readonly Expression replacement;
public ReplaceParamVisitor(ParameterExpression param, Expression replacement)
{
this.param = param;
this.replacement = replacement;
}
protected override Expression VisitParameter(ParameterExpression node) => node == param ? replacement : node;
}