次の方法で共有


言語統合クエリ (LINQ)

Language-Integrated クエリ (LINQ) は、クエリ機能を C# 言語に直接統合した一連のテクノロジの名前です。 従来、データに対するクエリは、コンパイル時または IntelliSense のサポート時に型チェックを行わずに単純な文字列として表現されていました。 さらに、SQL データベース、XML ドキュメント、さまざまな Web サービスなど、データ ソースの種類ごとに異なるクエリ言語を学習する必要があります。 LINQ では、クエリはクラス、メソッド、イベントと同様に、ファーストクラスの言語コンストラクトです。

クエリを記述する場合、LINQ の最も目に見える "言語統合" 部分はクエリ式です。 クエリ式は宣言型 クエリ構文で記述されます。 クエリ構文を使用すると、最小限のコードでデータ ソースに対してフィルター処理、順序付け、およびグループ化の操作を実行できます。 同じクエリ式パターンを使用して、任意の種類のデータ ソースからデータのクエリと変換を行います。

次の例は、完全なクエリ操作を示しています。 完全な操作には、データ ソースの作成、クエリ式の定義、 foreach ステートメントでのクエリの実行が含まれます。

// Specify the data source.
int[] scores = [97, 92, 81, 60];

// Define the query expression.
IEnumerable<int> scoreQuery =
    from score in scores
    where score > 80
    select score;

// Execute the query.
foreach (var i in scoreQuery)
{
    Console.Write(i + " ");
}

// Output: 97 92 81

前の例をコンパイルするには、 using ディレクティブ ( using System.Linq;) を追加する必要がある場合があります。 最新バージョンの .NET では、暗黙の using を利用して、このディレクティブをグローバル using として追加します。 以前のバージョンでは、ソースに追加する必要があります。

クエリ式の概要

  • クエリ式は、LINQ 対応データ ソースからデータのクエリと変換を行います。 たとえば、1 つのクエリで SQL データベースからデータを取得し、出力として XML ストリームを生成できます。
  • クエリ式では、多くの使い慣れた C# 言語コンストラクトが使用されるため、読みやすくなっています。
  • クエリ式の変数はすべて厳密に型指定されています。
  • クエリは、 foreach ステートメントなど、クエリ変数を反復処理するまで実行されません。
  • コンパイル時に、C# 仕様で定義されている規則に従って、クエリ式が標準のクエリ演算子メソッド呼び出しに変換されます。 クエリ構文を使用して表現できるクエリは、メソッド構文を使用して表現することもできます。 場合によっては、クエリ構文がより読みやすく簡潔になります。 それ以外の場合は、メソッド構文の方が読みやすいです。 2 つの異なる形式の間にセマンティックまたはパフォーマンスの違いはありません。 詳細については、 C# 言語仕様標準クエリ演算子の概要に関するページを参照してください。
  • CountMaxなどの一部のクエリ操作には同等のクエリ式句がないため、メソッド呼び出しとして表現する必要があります。 メソッド構文は、さまざまな方法でクエリ構文と組み合わせることができます。
  • クエリ式は、クエリが適用される型に応じて、式ツリーまたはデリゲートにコンパイルできます。 IEnumerable<T> クエリはデリゲートにコンパイルされます。 IQueryable クエリと IQueryable<T> クエリは式ツリーにコンパイルされます。 詳細については、「式ツリー」を参照してください。

データ ソースの LINQ クエリを有効にする方法

メモリ内データ

メモリ内データの LINQ クエリを有効にする方法は 2 つあります。 データが IEnumerable<T>を実装する型の場合は、LINQ to Objects を使用してデータのクエリを実行します。 IEnumerable<T> インターフェイスを実装して列挙を有効にしても意味がない場合は、その型で、またはその型の拡張メソッドとして LINQ 標準クエリ演算子メソッドを定義します。 標準クエリ演算子のカスタム実装では、遅延実行を使用して結果を返す必要があります。

リモートデータ

リモート データ ソースの LINQ クエリを有効にする最適なオプションは、 IQueryable<T> インターフェイスを実装することです。

IQueryable LINQ プロバイダー

IQueryable<T>を実装する LINQ プロバイダーは、複雑さが大きく異なる場合があります。

複雑でない IQueryable プロバイダーは、Web サービスから 1 つのメソッドにアクセスする可能性があります。 この種類のプロバイダーは、処理するクエリ内の特定の情報を必要とするため、非常に具体的です。 閉じた型システムがあり、おそらく単一の結果型を公開します。 クエリの実行のほとんどはローカルで実行されます。たとえば、標準クエリ演算子の Enumerable 実装を使用します。 複雑でないプロバイダーでは、クエリを表す式ツリー内のメソッド呼び出し式を 1 つだけ調べ、クエリの残りのロジックを他の場所で処理できます。

複雑さが中程度の IQueryable プロバイダーは、部分的に表現力の高いクエリ言語を持つデータ ソースを対象とする場合があります。 Web サービスを対象とする場合は、Web サービスの複数のメソッドにアクセスし、クエリがシークする情報に基づいて呼び出すメソッドを選択する可能性があります。 中程度の複雑さのプロバイダーは、単純なプロバイダーよりも豊富な型システムを持っていますが、固定型システムのままです。 たとえば、プロバイダーは、走査可能な一対多リレーションシップを持つ型を公開する可能性がありますが、ユーザー定義型のマッピング テクノロジは提供されません。

IQueryable プロバイダーなどの複雑な プロバイダーは、完全な LINQ クエリを SQL などの表現力豊かなクエリ言語に変換する場合があります。 複雑なプロバイダーは、クエリでさまざまな質問を処理できるため、より一般的です。 また、オープン型システムがあるため、ユーザー定義型をマップするための広範なインフラストラクチャを含める必要があります。 複雑なプロバイダーを開発するには、かなりの労力が必要です。