1

私には2つの表現があります:

  public static Expression<Func<TSource, TReturn>> Merge<TSource, TSource2, TReturn>(
      Expression<Func<TSource, TSource2>> foo1
      Expression<Func<TSource2, TReturn>> foo2)
  {
      // What to do?
  }

それらを単一の式にマージして、最初の式からの出力が2番目の式の入力として使用されるようにするにはどうすればよいですか?私はこれらに不慣れであり、これまでのところそれはただの例外でした。

ありがとう

4

1 に答える 1

1

これは、どのプロバイダーがそれを使用する必要があるかに大きく依存します。いくつかはうまくいくでしょう:

public static Expression<Func<TSource, TReturn>>
     Merge<TSource, TSource2, TReturn>(
  Expression<Func<TSource, TSource2>> foo1,
  Expression<Func<TSource2, TReturn>> foo2)
{
    return Expression.Lambda<Func<TSource, TReturn>>(
      Expression.Invoke(foo2, foo1.Body),
      foo1.Parameters);
}

ただし、他の人(EF)はそうしません。また、ビジターを使用して式ツリーを書き直し、式をインライン化することもできます。

public static Expression<Func<TSource, TReturn>>
      Merge<TSource, TSource2, TReturn>(
  Expression<Func<TSource, TSource2>> foo1,
  Expression<Func<TSource2, TReturn>> foo2)
{
    var swapped = new SwapVisitor(
        foo2.Parameters.Single(), foo1.Body).Visit(foo2.Body);
    return Expression.Lambda<Func<TSource, TReturn>>(
        swapped, foo1.Parameters);
}

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

これはすべてのプロバイダーで機能します。

于 2013-03-26T11:46:20.693 に答える