我如何可以将两个lambda表达式,而不使用Invoke方法?(How can I combine

2019-06-24 12:10发布

我有两个lambda表达式:

Expression<Func<MyEntity, bool>> e1 = i=>i.FName.Contain("john");

Expression<Func<MyEntity, bool>> e2=i=>i.LName.Contain("smith");

在I型,来自于我的POCO实体,不能与调用使用。 我想这些在运行结合起来。

我想这些表达式在运行时以类似的方式结合起来:

Expression<Func<MyEntity, bool>> e3 = Combine(e1,e2);

Answer 1:

问题是,你不能只是“和” /“或”他们,因为你需要重新编写的内部改变参数; 如果你使用的.Bodye1 ,但是从参数 e2 ,它不会工作-因为.Bodye1引用没有定义一个完全无关的参数实例。 如果你使用这是比较明显的:

Expression<Func<MyEntity, bool>> e1 = i => i.FName.Contains("john");
Expression<Func<MyEntity, bool>> e2 = j => j.LName.Contains("smith");

(注意之间的差e1使用ie2使用j

如果我们不重写参数将它们结合起来,我们会得到无意义的:

Expression<Func<MyEntity, bool>> combined =
         i => i.FName.Contains("john") && j.LName.Contains("smith");

(哇....哪里j从何而来?)

然而; 不管参数的名称的问题是相同的:它仍然是一个不同的参数。

而且,由于表达是不可变的,你不能只是换用“到位”了。

诀窍是使用“访问者”改写的节点,就像这样:

using System;
using System.Linq.Expressions;

class SwapVisitor : ExpressionVisitor
{
    private readonly Expression from, to;
    public SwapVisitor(Expression from, Expression to)
    {
        this.from = from;
        this.to = to;
    }
    public override Expression Visit(Expression node)
    {
        return node == from ? to : base.Visit(node);
    }
}

static class Program
{
    static void Main()
    {
        Expression<Func<MyEntity, bool>> e1 = i => i.FName.Contains("john");
        Expression<Func<MyEntity, bool>> e2 = i => i.LName.Contains("smith");

        // rewrite e1, using the parameter from e2; "&&"
        var lambda1 = Expression.Lambda<Func<MyEntity, bool>>(Expression.AndAlso(
            new SwapVisitor(e1.Parameters[0], e2.Parameters[0]).Visit(e1.Body),
            e2.Body), e2.Parameters);

        // rewrite e1, using the parameter from e2; "||"
        var lambda2 = Expression.Lambda<Func<MyEntity, bool>>(Expression.OrElse(
            new SwapVisitor(e1.Parameters[0], e2.Parameters[0]).Visit(e1.Body),
            e2.Body), e2.Parameters);
    }
}


Answer 2:

using (MyDataBaseEntities db = new MyDataBaseEntities())
    {
            {
                if (db.People.Any(p => p.FirstName == FirstNameText.Text && p.LastName == LastNameText.Text))
                            {
                                 //Do something
                            }
            }      
    }

也许有simpe if语句?

我是新顺便说一句,很抱歉,如果我的回答是一个愚蠢的一个。



文章来源: How can I combine two lambda expressions without using Invoke method?