のは、私はそうのように使用することができますFoo
にBar
を、「減らす」Expression<Func<Foo, Bar>>
calculateBar
を持っているとしましょうそう、それはTuple<Foo, Bar>
を返すことができるcalculateBar
をラップする:式とラムダを簡単に組み合わせる方法はありますか?</p> <pre><code>IQueryable foo = getFoos(); bars = foo.Select(calculateBar); </code></pre> <p>はしかし、私は時々、入力のFooを参照できるようにする必要がありますので、私はしたい:
public static Expression<Func<TIn, Tuple<TIn, TOut>>> WithInput<TIn, TOut>(
this Expression<Func<TIn, TOut>> expression)
{
var param = Expression.Parameter(typeof(TIn));
var constructor = typeof(Tuple<TIn, TOut>).GetConstructor(new[] { typeof(TIn), typeof(TOut) });
if (constructor == null) throw new ArgumentNullException();
return Expression.Lambda<Func<TIn, Tuple<TIn, TOut>>>(Expression.New(constructor, param, Expression.Invoke(expression, param)), param);
}
さて、その関数は、実際には、正常に動作します。ただし、LINQ-to-Entitiesでは、コンストラクタはパラメータなしでなければなりません。その代わりに、私は擬似タプル(new WithInput<Foo, Bar> { Input = theFoo, Output = theBar }
)を作成したいかもしれませんが、式として書くことはむしろ苦痛になるでしょう。
Expression
ツリーを引き続き作成する代わりに、Lambdaを使用して既存の式(LINQ-to-Entitiesを怒らせることなく)を構築する方法はありますか?例えば
(擬似コード):
Expression<Func<Foo, WithInput<Foo, Bar>>> wrapper = foo => new WithInput { Input = foo, Output = Expression.Invoke(calculateBar, foo) };
ブリリアント、おかげで、 'MemberInit'が大きいです。 –