用 ReplacingExpressionVisitor 替换自定义 ExpressionVisitor
Replace custom ExpressionVisitor with ReplacingExpressionVisitor
我可以使用下面的代码。
但是,与其像我一样使用自定义的 ParameterReplacer
class,我更愿意删除此 class 并改用 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));
实际上在组合之前替换参数更好:
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;
我可以使用下面的代码。
但是,与其像我一样使用自定义的 ParameterReplacer
class,我更愿意删除此 class 并改用 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));
实际上在组合之前替换参数更好:
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;