Language-Integrated Query (LINQ) という名前は、クエリ構文やその他の言語コンストラクトを言語で直接サポートする Visual Basic のテクノロジを指します。 LINQ では、外部データ ソースに対してクエリを実行するための新しい言語を学習する必要はありません。 Visual Basic を使用して、リレーショナル データベース、XML ストア、またはオブジェクト内のデータに対してクエリを実行できます。 クエリ機能を言語に統合することで、コンパイル時に構文エラーと型の安全性をチェックできます。 また、この統合により、Visual Basic で豊富で多様なクエリを記述するために知っておくべきことの大部分を既に把握できます。
以降のセクションでは、入門ドキュメント、コード例、サンプル アプリケーションを読み始めるのに十分な詳細な LINQ をサポートする言語コンストラクトについて説明します。 また、リンクをクリックすると、言語統合クエリを有効にするために言語機能がどのように連携するかについての詳細な説明が表示されます。 まず、 チュートリアル: Visual Basic でのクエリの記述を開始することをお勧めします。
クエリ式
Visual Basic のクエリ式は、SQL や XQuery と同様の宣言構文で表すことができます。 コンパイル時に、クエリ構文は、LINQ プロバイダーの標準クエリ演算子拡張メソッドの実装に対するメソッド呼び出しに変換されます。 アプリケーションは、 Imports
ステートメントで適切な名前空間を指定することで、スコープ内の標準クエリ演算子を制御します。 Visual Basic クエリ式の構文は次のようになります。
Dim londonCusts = From cust In customers
Where cust.City = "London"
Order By cust.Name Ascending
Select cust.Name, cust.Phone
詳細については、「Visual Basicでの LINQ の概要」を参照してください。
暗黙的に型指定された変数
変数を宣言して初期化するときに型を明示的に指定する代わりに、コンパイラが型を推論して割り当てることができる。 これは ローカル型推論と呼ばれます。
型が推論される変数は、明示的に指定した型の変数と同様に、厳密に型指定されます。 ローカル型の推論は、メソッド本体内でローカル変数を定義する場合にのみ機能します。 詳細については、「 Option Infer ステートメント 」および 「ローカル型推論」を参照してください。
次の例は、ローカル型の推論を示しています。 この例を使用するには、 Option Infer
を On
に設定する必要があります。
' The variable aNumber will be typed as an integer.
Dim aNumber = 5
' The variable aName will be typed as a String.
Dim aName = "Virginia"
ローカル型推論を使用すると、匿名型を作成することもできます。匿名型は、このセクションで後述し、LINQ クエリに必要です。
次の LINQ の例では、 Option Infer
が On
または Off
の場合に型推論が発生します。 コンパイル時エラーは、 Option Infer
が Off
され、 Option Strict
が On
場合に発生します。
' Query example.
' If numbers is a one-dimensional array of integers, num will be typed
' as an integer and numQuery will be typed as IEnumerable(Of Integer)--
' basically a collection of integers.
Dim numQuery = From num In numbers
Where num Mod 2 = 0
Select num
オブジェクト初期化子
オブジェクト初期化子は、クエリの結果を保持するために匿名型を作成する必要がある場合に、クエリ式で使用されます。 また、クエリの外部で名前付き型のオブジェクトを初期化するためにも使用できます。 オブジェクト初期化子を使用すると、コンストラクターを明示的に呼び出さずに、1 行でオブジェクトを初期化できます。 パブリック Name
プロパティとPhone
プロパティを持つ Customer
という名前のクラスを他のプロパティと共に使用すると、オブジェクト初期化子を次のように使用できます。
Dim aCust = New Customer With {.Name = "Mike",
.Phone = "555-0212"}
詳細については、「 オブジェクト初期化子: 名前付き型と匿名型」を参照してください。
匿名型
匿名型を使用すると、一連のプロパティをクエリ結果に含める要素に一時的にグループ化するのに便利です。 これにより、要素の名前付きデータ型を定義せずに、クエリで使用可能なフィールドの任意の組み合わせを任意の順序で選択できます。
匿名型は、コンパイラによって動的に構築されます。 型の名前はコンパイラによって割り当てられ、新しいコンパイルのたびに変更される可能性があります。 そのため、名前を直接使用することはできません。 匿名型は、次の方法で初期化されます。
' Outside a query.
Dim product = New With {.Name = "paperclips", .Price = 1.29}
' Inside a query.
' You can use the existing member names of the selected fields, as was
' shown previously in the Query Expressions section of this topic.
Dim londonCusts1 = From cust In customers
Where cust.City = "London"
Select cust.Name, cust.Phone
' Or you can specify new names for the selected fields.
Dim londonCusts2 = From cust In customers
Where cust.City = "London"
Select CustomerName = cust.Name,
CustomerPhone = cust.Phone
詳細については、「 匿名型」を参照してください。
拡張メソッド
拡張メソッドを使用すると、定義の外部からデータ型またはインターフェイスにメソッドを追加できます。 この機能を使用すると、実際に型を変更することなく、既存の型に新しいメソッドを追加できます。 標準クエリ演算子自体は、 IEnumerable<T>を実装する任意の型に LINQ クエリ機能を提供する拡張メソッドのセットです。 IEnumerable<T>のその他の拡張機能には、Count、Union、およびIntersectが含まれます。
次の拡張メソッドは、 String クラスに print メソッドを追加します。
' Import System.Runtime.CompilerServices to use the Extension attribute.
<Extension()>
Public Sub Print(ByVal str As String)
Console.WriteLine(str)
End Sub
このメソッドは、 Stringの通常のインスタンス メソッドと同様に呼び出されます。
Dim greeting As String = "Hello"
greeting.Print()
詳細については、「拡張メソッド」を参照してください。
ラムダ式
ラムダ式は、1 つの値を計算して返す名前のない関数です。 名前付き関数とは異なり、ラムダ式を同時に定義して実行できます。 次の例では、4 が表示されます。
Console.WriteLine((Function(num As Integer) num + 1)(3))
ラムダ式の定義を変数名に割り当ててから、その名前を使用して関数を呼び出すことができます。 次の例では、4 も表示されます。
Dim add1 = Function(num As Integer) num + 1
Console.WriteLine(add1(3))
LINQ では、ラムダ式は多くの標準クエリ演算子の基になります。 コンパイラはラムダ式を作成して、 Where
、 Select
、 Order By
、 Take While
などの基本的なクエリ メソッドで定義されている計算をキャプチャします。
たとえば、次のコードでは、学生の一覧からすべての上級学生を返すクエリを定義します。
Dim seniorsQuery = From stdnt In students
Where stdnt.Year = "Senior"
Select stdnt
クエリ定義は、次の例のようなコードにコンパイルされ、2 つのラムダ式を使用して Where
と Select
の引数を指定します。
Dim seniorsQuery2 = students.
Where(Function(st) st.Year = "Senior").
Select(Function(s) s)
どちらのバージョンも、 For Each
ループを使用して実行できます。
For Each senior In seniorsQuery
Console.WriteLine(senior.Last & ", " & senior.First)
Next
詳細については、「 ラムダ式」を参照してください。
こちらも参照ください
.NET