13

匿名の C# メソッドでローカル変数を使用することは可能です。つまり、次のコードでは、カウントを 1 回だけ実行したいと考えています。

IQueryable<Enquiry> linq = db.Enquiries;

if(...) linq = linq.Where(...);

if(...) linq = linq.Where(e => 
    (x <= (from p in db.Orders where p.EnquiryId == e.Id select p).Count() && 
        (from p in db.Orders where p.EnquiryId == e.Id select p).Count() <= y));

if(...) linq = linq.Where(...);

var result = (from e in linq select e);

匿名関数の「let」はありますか?

更新: このステートメントの後にいくつかの Where 句を追加しているため、select で閉じることができないことに注意してください。

/ニールス

4

6 に答える 6

26

はい、なぜですか?結局のところ、それは関数であり、匿名です!

例:

 x => { int y = x + 1; return x + y; }

または、次のようにします。

 delegate(int x) {
     int y = x + 1;
     return x + y;
 }

したがって、コードは次のように記述できます。

  ... = linq.Where(e => {
         var count = (from p in db.Orders where p.EnquiryId == e.Id select p).Count();
         return x <= count && count <= y;
  });

更新: コメントについて明確にするために、匿名メソッドとラムダ式の違いを知ることが重要です。匿名メソッドは、明示的な名前がない通常のメソッドと同じです。コンパイルすると、代わりに奇妙な名前の通常のメソッドがコンパイラによって生成されるため、特別な制限はありません。ただし、無名メソッドの 1 つの表現はラムダ式です。ラムダ式は、いくつかの異なる方法で解釈できます。1つ目はデリゲートです。その意味で、匿名メソッドと同等です。2 つ目は式ツリーです。この方法は通常、LINQ to SQL およびその他の LINQ プロバイダーで使用されます。彼らは決して式を直接実行しません。それを式ツリーとして解析し、そのツリーを入力データとして使用して、サーバーで実行される同等の SQL ステートメントを生成します。メソッドのように実行されず、匿名メソッドとは見なされません。その場合、ラムダを式ツリーとして解析できないため、ローカル変数を定義できません。

于 2008-12-15T18:51:59.077 に答える
7

はい、LinqからオブジェクトおよびLinqからSQLで、必要なことを正確に実行できます。

Linqにはがあり、let必要に応じて、クエリの途中で中間結果に名前を付けることができます。あなたの例に基づいて:

... = from e in linq 
      let count = (from p in db.Orders where p.EnquiryId == e.Id select p).Count()
      where (x <= count) && (count <= y)
      select e;

ちなみに、元の例には構文的に誤りがあったと思います。これはcount、名前だけの場合に見つけやすくなります。

where (x <= count) && /* <= */ (count <= y);
于 2008-12-15T19:10:28.523 に答える
2

Linq to SQL を使用している場合、Mehrdad Afshari の回答は使用できません。LINQ 式は式ツリーである必要があり、それらは匿名デリゲート構文をサポートしていません。

他の場所でデリゲートを作成してラムダ内から呼び出すこともできません.Linq to SQLでは、クエリの本文で特定の操作を実行することしかできず、デリゲートの呼び出しはその1つではありません.

Linq to SQL を使用していると仮定すると (例に示されているように)、1 つのクエリでカウントを下げてから、カウントを必要とするクエリでカウント変数をキャプチャすることをお勧めします。

于 2008-12-15T19:01:40.117 に答える
1

Where メソッドは Func を受け取るため、2 番目の部分で渡されるものは、実際にはメソッドではなく、単なるブール式です。私の提案は、ブール値を返し、必要なパラメーターを受け取る実際のメソッドを用意することです。Where メソッドの呼び出しでは、次のようなことを行います Where(p=> MyMethod(p,...))

于 2008-12-15T18:57:31.500 に答える
0

私は同様の問題に遭遇しました。解決策は、カスタム式ツリー生成メソッドを作成することです。

MSDN フォーラムで質問しました。こちらの質問と回答を参照してください: Reusing Where expressions

これにより、先に進む方法についてのアイデアが得られるかもしれませんが、カスタム式ツリーは気弱な人向けではないことを認めなければなりません ;-)

于 2008-12-23T23:26:00.043 に答える