取消绑定参数

本文关键字:参数 绑定 取消 | 更新日期: 2023-09-27 17:57:08

all

我尝试通过表达式树构建动态 linq 查询,下面是我的代码

        Expression<Func<User, bool>> filter = c => c.isAdmin == false;
        Expression<Func<User, bool>> filterForExistUser = c => (c.isfreezed == null ? false : c.isfreezed) != true;
        Expression<Func<User, bool>> finalFilter = Expression.Lambda<Func<User, bool>>(Expression.AndAlso(filter.Body, filterForExistUser.Body), filter.Parameters);
        IQueryable<User> myusers = db.Users.AsQueryable<User>();
        MethodCallExpression whereCallExpression = Expression.Call(
            typeof(Queryable),
            "Where",
            new Type[] { myusers.ElementType },
            myusers.Expression,
            finalFilter);
        IQueryable<User> results = myusers.Provider.CreateQuery<User>(whereCallExpression);
        foreach (User user in results)
            Console.WriteLine(user.UserName);

但是系统报告"unding参数c"错误,我该如何解决?

谢谢

取消绑定参数

尽管 filterfilterForExistUser 表达式中的参数共享相同的名称,但它们都引用来自不同作用域的不同符号。 新表达式使用filter表达式中的参数,但省略了filterForExistUser的参数。 必须重写表达式,以便在整个表达式中使用相同的单个参数。

下面是可用于组合谓词的通用方法:

Expression<Func<TSource, bool>> CombinePredicates<TSource>(
    Expression<Func<TSource, bool>> head,
    params Expression<Func<TSource, bool>>[] tail)
{
    var param = head.Parameters.Single();
    var body = tail.Aggregate(
        head.Body,
        (result, expr) => Expression.AndAlso(result,
            new SubstitutionVisitor
            {
                OldExpr = expr.Parameters.Single(),
                NewExpr = param,
            }.Visit(expr.Body)
        )
    );
    return Expression.Lambda<Func<TSource, bool>>(body, param);
}
public class SubstitutionVisitor : ExpressionVisitor
{
    public Expression OldExpr { get; set; }
    public Expression NewExpr { get; set; }
    public override Expression Visit(Expression node)
    {
        return (node == OldExpr) ? NewExpr : base.Visit(node);
    }
}

关键是用于使用 "head" 参数替换 "tail" 参数的 SubstitutionVisitor

所以你的最终过滤器变成这样:

Expression<Func<User, bool>> finalFilter =
    CombinePredicates(filter, filterForExistUser);