2009-05-07 7 views
2

:ここに何が起こるかアルゴリズムLINQでのコーディングはどのように機能しますか?舞台裏ではどうなりますか?たとえば

m_lottTorqueTools = (From t In m_lottTorqueTools _ 
        Where Not t.SlotNumber = toolTuple.SlotNumber _ 
        And Not t.StationIndex = toolTuple.StationIndex).ToList 

?バックグラウンドで入れ子になっているforループがありますか?これらのフィールドのハッシュテーブルを構築していますか?私は興味がある。

答えて

6

クエリ式は、通常は、拡張メソッドの呼び出しに変換されます。 (彼らはがするを持っていませんが、クエリの99.9%がIEnumerable<T>またはIQueryable<T>を使用しています。)

そのメソッドが何をするかの正確なアルゴリズムはメソッドからメソッドに変わります。サンプルクエリではハッシュテーブルは使用されませんが、ジョインやグループ化操作などがあります。述語が提供され

public static IEnumerable<T> Where(this IEnumerable<T> source, 
    Func<T, bool> predicate) 
{ 
    // Argument checking omitted 
    foreach (T element in source) 
    { 
     if (predicate(element)) 
     { 
      yield return element; 
     } 
    } 
} 

シンプルWhereコールは、(私は承知している限り、現時点ではVBで利用できない反復子ブロックを、使用して)C#でこのような何かに変換しますデリゲート(またはIQueryable<T>を使用している場合は式ツリー)を呼び出し、シーケンス内の各アイテムに対して呼び出されます。結果はストリーミングされ、実行は延期されます。つまり、結果から項目を要求するまでは何も起こりません。さらに次の結果を得るために必要なだけの処理を行います。いくつかの演算子は、(シーケンスの代わりに単一の値を返す基本的なものを)延期されていないといくつかの入力をバッファ(例えばReverseは、それがどんな結果を返すことができます前に、最後の結果はそれを読み取るため、シーケンスの最後まで読まなければなりません最初に収穫しなければならないものです)。

それは、私は怖いが、あなたは特定のものについて質問がある場合、私たちは義務付けることができると確信していひとつひとつのLINQ演算子の詳細を与えるために、単一の答えの範囲を超えています。

LINQ to SQLまたはIQueryable<T>に基づいた別のプロバイダを使用している場合は、状況がかなり異なることを付け加えておきます。 Queryableクラスは、(IQueryable<T>を実装するプロバイダの助けを借りて)クエリを構築し、その後、クエリは一般にプロバイダによってより適切な形式(例えばSQL)に変換される。正確な詳細(バッファリング、ストリーミングなどを含む)は完全にプロバイダに依存します。

+0

恐ろしいです。素晴らしい返信。ありがとう、ジョン。 – Daniel

1

何が起こるかは、メソッドに依存するだけでなく、使用しているLINQプロバイダによっても異なります。 IQueryable<T>が返されている場合は、式ツリーを解釈し、それを処理するのはLINQプロバイダです。一般的には

1

LINQは、舞台裏で起こってたくさんを持っています。任意のクエリでは、最初にIQueryableProviderを使用して式ツリーに変換され、そこからクエリは通常、CILコードにコンパイルされ、デリゲートは、この関数を指して生成され、クエリを呼び出すたびに、基本的に使用しています。それは非常に単純化された概観です - もしあなたがその件に関して偉大な記事を読もうとするなら、私はHow LINQ Works - Creating Queriesを見ることをお勧めします。 Jon Skeetもこのサイトで良い答えをthis questionに投稿しました。

関連する問題