问题
If I've got a LINQ expression of the form:
Expression<Func<MyClass, string, bool>> filterExpression = (x, filterVal) => x.DisplayName.Contains(filterVal);
Is there any way I can get to the expression below?
Expression<Func<MyClass, bool>> filter = x => x.DisplayName.Contains("John");
I need to use the second expression in a Linq-to-Entities Where call.
回答1:
You need to write an ExpressionVisitor that replaces the ParameterExpression
with a ConstantExpression
.
It would look something like
protected override Expression VisitParameter(ParameterExpression node) {
if (node.Name == "filterVal")
return Expression.Constant(something);
return node;
}
回答2:
In case it's useful the way I solved it was:
public class MyVisitor : ExpressionVisitor
{
protected override Expression VisitParameter(ParameterExpression node)
{
Console.WriteLine("Visiting Parameter: " + node.Name);
if (node.Name == "filterVal")
{
return Expression.Constant("John");
}
return node;
}
}
Expression<Func<MyClass, string, bool>> filterExpression = (x, filterVal) => x.DisplayName.Contains(filterVal);
var filterExpBody = (new MyVisitor()).Visit(filterExpression.Body);
Expression<Func<MyClass, bool>> filter = Expression.Lambda<Func<MyClass, bool>>(filterExpBody, filterExpression.Parameters[0]);
来源:https://stackoverflow.com/questions/6012689/build-a-specific-linq-expression-based-on-another-linq-expression-and-a-value