20

私は2つのラムダ式を持っています:

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

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

i タイプは、invoke では使用できない私の poco エンティティから来ています。これらを実行時に組み合わせたい。

これらの式を実行時に次のように組み合わせたいと思います。

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

2 に答える 2

59

問題は、パラメータを変更するために内部を書き直す必要があるため、それらを単に「and」/「or」できないことです。.Bodyfromを使用してe1パラメータfromを使用すると、機能しません。 ofは、定義されていない完全に無関係なパラメータ インスタンスを参照する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);
    }
}
于 2012-05-16T07:08:26.400 に答える