【问题标题】:Replace custom ExpressionVisitor with ReplacingExpressionVisitor将自定义 ExpressionVisitor 替换为 ReplaceingExpressionVisitor
【发布时间】:2021-08-04 03:07:52
【问题描述】:

我有下面的代码工作。

但是,与其像我一样使用自定义的ParameterReplacer 类,我更愿意消除这个类并改用ReplacingExpressionVisitor。但是我似乎找不到正确的语法来获取现有参数,以便可以将其替换为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));

【问题讨论】:

    标签: c# linq expression-trees .net-5


    【解决方案1】:

    其实在合并之前最好先替换参数:

    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 的参数,则不需要替换。

    // 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;
    

    【讨论】:

      猜你喜欢
      • 2022-08-19
      • 1970-01-01
      • 2022-07-24
      • 2020-02-04
      • 1970-01-01
      • 2021-12-27
      • 2023-03-22
      • 1970-01-01
      • 2020-07-19
      相关资源
      最近更新 更多