将两个 lambda 表达式与内部表达式组合

Ref*_*ion 2 c# linq lambda expression predicate

我有下一个类结构:

    public class Order
    {
        public User User { get; set; }
        public string Name { get; set; }
    }

    public class Authentication
    {
        public string Email { get; set; }      
    }

    public class User
    {
        public string Name { get; set; }
        public List<Authentication> Auths { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

我正在尝试在运行时构建一个表达式,以按 User.Name、Order.Name 或 User.Auths.Email 搜索实体

我试图组合三个表达式:

    Expression<Func<Order, bool>> usernameExpression = order => order.Name.Contains(searchValue);
    Expression<Func<Order, bool>> nameExpression = order => order.User.Name.Contains(searchValue);
    Expression<Func<Order, bool>> emailExpression = order => order.User.Auths.Any(auth => auth.Email.Contains(searchValue));
Run Code Online (Sandbox Code Playgroud)

我使用此线程中的 ParameterReplacer 成功组合了两个第一个表达式:如何组合两个 lambda

但是,当将结果表达式与电子邮件表达式组合时,我收到下一个错误:

Property 'System.String Email' is not defined for type Order'
Run Code Online (Sandbox Code Playgroud)

看起来作用域对内部“auth”参数一无所知。是否可以创建表达式而不从头开始重建它?

Iva*_*oev 7

您使用的ParameterReplacer过于简化,盲目地替换每个参数。

使用这个代替:

public static class ExpressionUtils
{
    public static Expression ReplaceParameter(this Expression expression, ParameterExpression source, Expression target)
    {
        return new ParameterReplacer { Source = source, Target = target }.Visit(expression);
    }

    class ParameterReplacer : ExpressionVisitor
    {
        public ParameterExpression Source;
        public Expression Target;
        protected override Expression VisitParameter(ParameterExpression node)
        {
            return node == Source ? Target : base.VisitParameter(node);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

或者使用thisthis谓词构建器助手。