如何复用实体IsActive表达式合并SchedulePackage的AndAlso查询条件?
复用实体IsActive表达式组合关联类的活跃判断
要复用Package和Schedule的IsActive表达式来构建SchedulePackage的活跃判断逻辑,核心是替换表达式的参数节点,将针对单个实体的表达式转换为针对关联类的表达式,再通过Expression.AndAlso合并。
1. 实现表达式参数替换工具
首先需要一个工具方法,用于将表达式中的原始参数替换为关联类的属性访问表达式:
using System.Linq.Expressions; public static class ExpressionExtensions { public static Expression<Func<TTarget, bool>> ReplaceParameter<TSource, TTarget>( this Expression<Func<TSource, bool>> sourceExpr, Expression<Func<TTarget, TSource>> propertyAccessor) { var parameterReplacer = new ParameterReplacer( sourceExpr.Parameters[0], propertyAccessor.Body); var newBody = parameterReplacer.Visit(sourceExpr.Body); return Expression.Lambda<Func<TTarget, bool>>(newBody, propertyAccessor.Parameters); } private class ParameterReplacer : ExpressionVisitor { private readonly ParameterExpression _oldParam; private readonly Expression _newExpr; public ParameterReplacer(ParameterExpression oldParam, Expression newExpr) { _oldParam = oldParam; _newExpr = newExpr; } protected override Expression VisitParameter(ParameterExpression node) { return node == _oldParam ? _newExpr : base.VisitParameter(node); } } }
2. 构建SchedulePackage的IsActive表达式
借助上面的工具方法,直接复用两个实体的IsActive逻辑,无需手动复制代码:
class SchedulePackage { public Package Package { get; init; } public Schedule Schedule { get; init; } public static Expression<Func<SchedulePackage, bool>> IsActive = Package.IsActive.ReplaceParameter((SchedulePackage sp) => sp.Package) .AndAlso(Schedule.IsActive.ReplaceParameter((SchedulePackage sp) => sp.Schedule)); }
补充AndAlso扩展方法用于合并表达式:
public static class ExpressionExtensions { public static Expression<Func<T, bool>> AndAlso<T>( this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right) { var parameter = Expression.Parameter(typeof(T)); var leftBody = new ParameterReplacer(left.Parameters[0], parameter).Visit(left.Body); var rightBody = new ParameterReplacer(right.Parameters[0], parameter).Visit(right.Body); return Expression.Lambda<Func<T, bool>>( Expression.AndAlso(leftBody, rightBody), parameter); } // 上述ReplaceParameter和ParameterReplacer代码放在此处 }
效果验证
当Package的IsActive更新为:
public static Expression<Func<Package, bool>> IsActive => x => x.Enabled && x.Price > 0;
SchedulePackage.IsActive会自动继承这个新逻辑,无需手动修改关联类代码,完全复用实体的判断规则。
内容的提问来源于stack exchange,提问作者Parsa99
相关产品推荐
相关产品推荐

