0

次のように定義された 2 つの式ツリーがあります。

Expression<Func<string, bool>> BoolExpression { get; }

Expression<Func<Customer, string>> PropertyExpression { get; }

次のような結果になる新しい式ツリーを作成する必要があります。

Customer c = null;
var expression = e1(e2(c));

Compile()、Invoke() で実行できます。

Customers c = null;
var e3 = e1.Compile().Invoke(e2.Compile().Invoke(c));

しかし、EntityDataModel を使用しているため、Compile または Invoke メソッドを使用できません。「式」をWhereメソッドに渡すと、SQLクエリに変換されてデータベースに渡されます。

PS: EntityDataModel を使用してある種のクエリ ビルダーを実行したいと考えています。n フィールドと m 条件があります。フィールドに n 式、条件に m 式を定義して結合したい。

4

1 に答える 1

0

オプション1

これを最初に試してみてください-LINQ-to-SQLで試してみたところ、EFで動作するはずです。それはあなたが持っていたものから百万マイルではなく、e2を呼び出した結果でe1を呼び出すと言っているだけです:

var e3 = Expression.Lambda<Func<Customer, bool>>(Expression.Invoke(e1, Expression.Invoke(e2, e2.Parameters)), e2.Parameters);

オプション2

式ツリーをたどって、BoolExpression関数のStringパラメーターの使用法を置き換える必要があると思っていました。次のようになります。

// replace parameter use anywhere in e1.Body with e2.Body
var remover = new ParameterReplaceVisitor(e2.Body);
var bb = remover.Visit(e1.Body);

// create a new lambda with our amended body but still with e2 parameters i.e. the Customer
var e3 = Expression.Lambda<Func<Customer, bool>>(bb, e2.Parameters);

public class ParameterReplaceVisitor : ExpressionVisitor
{
    Expression _replace;

    public ParameterReplaceVisitor(Expression replace)
    {
        _replace = replace;
    }

    protected override Expression VisitParameter(ParameterExpression node)
    {
        // when we encounter a parameter replace it
        return _replace;
    }
}

明らかに、式に複数のパラメーターを導入すると、状況は少し複雑になります。

于 2012-04-25T23:52:22.517 に答える