用 ReplacingExpressionVisitor 替换自定义 ExpressionVisitor [英] Replace custom ExpressionVisitor with ReplacingExpressionVisitor

查看:24
本文介绍了用 ReplacingExpressionVisitor 替换自定义 ExpressionVisitor的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有下面的代码工作.

但不是像我一样使用自定义的 ParameterReplacer 类,我更希望我能消除这个类并使用 ReplaceExpressionVisitor 代替.但我似乎找不到正确的语法来获取现有参数,以便我可以用 parameter 替换它.

But instead of using the custom ParameterReplacer class like I am, I would prefer if I could eliminate this class and use ReplacingExpressionVisitor instead. But I can't seem to find the right syntax where I can get the existing parameter so that I can replace it with parameter.

protected readonly Expression<Func<T, DateTime>> GetDateExpression;

参数替换器

internal class ParameterReplacer : ExpressionVisitor
{
    private readonly ParameterExpression Parameter;

    internal ParameterReplacer(ParameterExpression parameter)
    {
        Parameter = parameter;
    }

    protected override Expression VisitParameter(ParameterExpression node)
    {
        return base.VisitParameter(Parameter);
    }
}

主要代码

Expression expression;
Expression startExpression, endExpression;

// Build sub expressions
var parameter = Expression.Parameter(typeof(T));
startExpression = startDate.HasValue ?
    Expression.GreaterThanOrEqual(GetNullableDateExpression.Body, Expression.Constant(startDate, typeof(DateTime?))) :
    null;
endExpression = endDate.HasValue ?
    Expression.LessThanOrEqual(GetNullableDateExpression.Body, Expression.Constant(endDate, typeof(DateTime?))) :
    null;

// Build main expression
if (startExpression != null && endExpression != null)
    expression = Expression.AndAlso(startExpression, endExpression);
else if (startExpression != null)
    expression = startExpression;
else
    expression = endExpression;

// TODO: Change to use ReplacingExpressionVisitor instead

// Use our real parameter
expression = new ParameterReplacer(parameter)
    .Visit(expression);

// Modify query
return query.Where(Expression.Lambda<Func<T, bool>>(expression, parameter));

推荐答案

其实在组合前替换参数更好:

Actually better to replace parameter before combining:

Expression expression;
Expression startExpression, endExpression;

// Build sub expressions
var parameter = Expression.Parameter(typeof(T));

var nullableExpressionBody = ReplacingExpressionVisitor.Replace(GetNullableDateExpression.Body, GetNullableDateExpression.Parameters[0], parameter);

startExpression = startDate.HasValue ?
    Expression.GreaterThanOrEqual(nullableExpressionBody, Expression.Constant(startDate, typeof(DateTime?))) :
    null;
endExpression = endDate.HasValue ?
    Expression.LessThanOrEqual(nullableExpressionBody, Expression.Constant(endDate, typeof(DateTime?))) :
    null;

// Build main expression
if (startExpression != null && endExpression != null)
    expression = Expression.AndAlso(startExpression, endExpression);
else if (startExpression != null)
    expression = startExpression;
else
    expression = endExpression;

// Modify query
return query.Where(Expression.Lambda<Func<T, bool>>(expression, parameter));

此外,如果您重用来自 GetNullableDateExpression lambda 的参数,则不需要替换.

Also if you reuse parameter from GetNullableDateExpression lambda, replacing is not needed.

// Build sub expressions
var parameter = GetNullableDateExpression.Parameters[0];

startExpression = startDate.HasValue ?
    Expression.GreaterThanOrEqual(GetNullableDateExpression.Body, Expression.Constant(startDate, typeof(DateTime?))) :
    null;
endExpression = endDate.HasValue ?
    Expression.LessThanOrEqual(GetNullableDateExpression.Body, Expression.Constant(endDate, typeof(DateTime?))) :
    null;

这篇关于用 ReplacingExpressionVisitor 替换自定义 ExpressionVisitor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆