如何更改已创建的表达式?

How can I change already created Expression?

我有点关注class:

public class Entity
{
    public int Id { get; set; }
    public string Name { get; set; }
}

我正在将 IEnumerable<Entity>> 作为数据源传递给 kendo 网格(我认为这无关紧要,但为了清楚问题而添加到此处)。

我想实现服务器端过滤,并在页面上实现了一个单独的input[text]字段,并通过以下方式在客户端添加过滤器:

var grid = $(e).data('kendoGrid');
var columns = grid.columns;
var columnTypes = grid.dataSource.options.schema.model.fields;
for (var i = 0; i < columns.length; i++) {
    if (columns[i].field) {
        var columnDataType = columnTypes[columns[i].field].type;
        if (columnDataType == 'number' && !isNaN(Number(value))) {
            var filter = { field: columns[i].field, operator: "eq", value: Number(value) };
        } else if (columnDataType == 'string') {
            var filter = { field: columns[i].field, operator: "contains", value: value };
        }

        gridListFilter.filters.push(filter);
    }
}

var gridDataSource = grid.dataSource;
console.log(gridListFilter);
gridDataSource.filter(gridListFilter);

在服务器端,我在虚拟化处理程序方法中实现了以下过滤算法:

IQueryable<Entity> query = this.GetQuery<Entity>();
foreach (var item in dataSourceRequest.Filters)
{
    var paramExpr = Expression.Parameter(typeof(TReturnType), "item");
    var expr = item.CreateFilterExpression(paramExpr);
    var lambda = Expression.Lambda<Func<TReturnType, bool>>(expr, paramExpr);
    query = query.Where(lambda);
}

其中 dataSourceRequest 是来自 telerik 库的 DataSourceRequest 类型。 item.CreateFilterExpression 产生以下表示的 BinaryExpression 的事项:

item => (IIF((item != null), item.Id, 0) == 6999142) OrElse 
((IIF((item != null), item.Name, null) ?? "").ToLower().Contains("6999142".ToLower()))

其中“6999142”是我从 input[text] 视图中获得的搜索字符串。我想按以下方式修改此表达式:

item => (IIF((item != null), item.Id, 0).ToString().Contains("6999142")) OrElse 
((IIF((item != null), item.Name, null) ?? "").ToLower().Contains("6999142".ToLower()))

有没有一种方法可以更改已创建的 Expression 而无需重新创建新的?

如果是,能不能提供一下修改的示例代码,我也不知道从何入手。

根据@JonSkeet 的评论,我已经实现了以下

internal class KendoExpressionModifier : ExpressionVisitor
{
    public Expression Modify(Expression expression)
    {
        return Visit(expression);
    }

    protected override Expression VisitConditional(ConditionalExpression node)
    {
        //converting result of conditional expression to string
        return Expression.Call(node.IfTrue, typeof(object).GetMethod("ToString"));
    }

    protected override Expression VisitBinary(BinaryExpression node)
    {
        //replacing '==' operator with '.Contains'
        if (node.NodeType == ExpressionType.Equal)
        {
            var left = this.Visit(node.Left);
            var right = this.Visit(node.Right);

            return Expression.Call(left, typeof(string).GetMethod("Contains"), right);
        }
        //replacing expression 'a.ToString() ?? ""' with 'a != null ? a.ToString() : ""'
        else if (node.NodeType == ExpressionType.Coalesce)
        {
            var left = this.Visit(node.Left) as MethodCallExpression;

            return Expression.Condition(
                Expression.MakeBinary(
                    ExpressionType.NotEqual, 
                    left.Object, 
                    Expression.Constant(null)), 
                left, 
                Expression.Constant(string.Empty));
        }

        return base.VisitBinary(node);
    }

    protected override Expression VisitConstant(ConstantExpression node)
    {
        //replacing constant numeric value with its string representation
        if (node.Value.GetType() != typeof(string))
        {
            return Expression.Call(node, typeof(object).GetMethod("ToString"));
        }

        return base.VisitConstant(node);
    }
}

以及对这个修饰符的调用:

var kendoExpressionModifier = new KendoExpressionModifier();
expr = kendoExpressionModifier.Modify(expr);

生成所需的结果。所以,我希望它能对某人有所帮助。