将两个lambda表达式与内部表达式组合 [英] Combine two lambda expressions with inner expression

查看:157
本文介绍了将两个lambda表达式与内部表达式组合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有下一个类结构:

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

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

I'm trying to build an expression at runtime to search entities by User.Name, Order.Name or User.Auths.Email

我正在尝试组合三个表达式:

There are three expressions I'm trying to combine:

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

我使用ParameterReplacer从这个线程成功组合了两个第一个表达式:如何组合两个羊羔

I successfully combined two first expressions using ParameterReplacer from this thread: How to Combine two lambdas

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

However, when combining resulting expression with email expression I get the next error:

Property 'System.String Email' is not defined for type Order'

看起来范围并不知道内部的'auth'参数。
可以从头开始重新编写表达式吗?

Looks like the scope doesn't know anything about inner 'auth' parameter. Is it possible to creeate the expression without rebuilding it from scratch?

推荐答案

您使用的ParameterReplacer太简化了并且盲目地替换每个参数。

The ParameterReplacer you have used is too simplified and blindly replaces every parameter.

使用此代替:

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);
        }
    }
}

或使用这个这个谓语构建者助手。

Or use this or this predicate builder helpers.

这篇关于将两个lambda表达式与内部表达式组合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆