このチュートリアルでは、Visual Basic 言語機能を使用して、Language-Integrated クエリ (LINQ) クエリ式を記述する方法について説明します。 このチュートリアルでは、Student オブジェクトの一覧に対してクエリを作成する方法、クエリを実行する方法、およびクエリを変更する方法を示します。 クエリには、オブジェクト初期化子、ローカル型推論、匿名型など、いくつかの機能が組み込まれています。
このチュートリアルを完了すると、関心のある特定の LINQ プロバイダーのサンプルとドキュメントに進む準備が整います。 LINQ プロバイダーには、LINQ to SQL、LINQ to DataSet、LINQ to XML が含まれます。
プロジェクトを作成する
コンソール アプリケーション プロジェクトを作成するには
Visual Studio を起動します。
[ファイル] メニューの [新規作成] をポイントし、 [プロジェクト] をクリックします。
[ インストールされているテンプレート ] の一覧 で、[Visual Basic] をクリックします。
プロジェクトの種類の一覧で、[ コンソール アプリケーション] をクリックします。 [ 名前 ] ボックスにプロジェクトの名前を入力し、[OK] をクリック します。
プロジェクトが作成されます。 既定では、System.Core.dllへの参照が含まれています。 また、プロジェクト デザイナー (Visual Basic) の [参照] ページの [インポートされた名前空間] リストには、System.Linq名前空間が含まれています。
[ コンパイル] ページのプロジェクト デザイナー (Visual Basic)で、オプション推論 が [オン] に設定されていることを確認します。
In-Memory データ ソースを追加する
このチュートリアルのクエリのデータ ソースは、 Student
オブジェクトの一覧です。 各 Student
オブジェクトには、名、姓、学年、学生団体内での学業成績が含まれています。
データ ソースを追加するには
Student
クラスを定義し、クラスのインスタンスの一覧を作成します。Von Bedeutung
Student
クラスを定義し、チュートリアルの例で使用するリストを作成するために必要なコードについては、「方法: 項目のリストを作成する」を参照してください。 そこからコピーしてプロジェクトに貼り付けることができます。 新しいコードは、プロジェクトの作成時に表示されたコードを置き換えます。
新しい学生を学生の一覧に追加するには
-
getStudents
メソッドのパターンに従って、Student
クラスの別のインスタンスを一覧に追加します。 学生を追加すると、オブジェクト初期化子が挿入されます。 詳細については、「 オブジェクト初期化子: 名前付き型と匿名型」を参照してください。
クエリを作成する
このセクションで追加されたクエリを実行すると、学術的ランクが上位 10 位に入っている学生の一覧が生成されます。 クエリは毎回完全な Student
オブジェクトを選択するため、クエリ結果の型は IEnumerable(Of Student)
。 ただし、通常、クエリの種類はクエリ定義では指定されません。 代わりに、コンパイラはローカル型推論を使用して型を決定します。 詳細については、「 ローカル型の推論」を参照してください。 クエリの範囲変数 currentStudent
は、ソース内の各 Student
インスタンスへの参照として機能し、 students
、 students
内の各オブジェクトのプロパティへのアクセスを提供します。
単純なクエリを作成するには
次のようにマークされているプロジェクトの
Main
メソッド内の場所を見つけます。' ****Paste query and query execution code from the walkthrough, ' ****or any code of your own, here in Main.
次のコードをコピーして貼り付けます。
Dim studentQuery = From currentStudent In students Where currentStudent.Rank <= 10 Select currentStudent
コード内の
studentQuery
上にマウス ポインターを置き、コンパイラ割り当て型がIEnumerable(Of Student)
されていることを確認します。
クエリを実行する
studentQuery
変数には、クエリの実行結果ではなく、クエリの定義が含まれています。 クエリを実行するための一般的なメカニズムは、 For Each
ループです。 返されたシーケンス内の各要素は、ループ反復変数を介してアクセスされます。 クエリの実行の詳細については、「 最初の LINQ クエリの記述」を参照してください。
クエリを実行するには
プロジェクトのクエリの下に、次の
For Each
ループを追加します。For Each studentRecord In studentQuery Console.WriteLine(studentRecord.Last & ", " & studentRecord.First) Next
ループ コントロール変数の上にマウス ポインターを置
studentRecord
、そのデータ型を確認します。studentRecord
はStudent
インスタンスのコレクションを返すので、studentQuery
の型はStudent
と推定されます。Ctrl キーを押しながら F5 キーを押して、アプリケーションをビルドして実行します。 コンソール ウィンドウで結果を確認します。
クエリを変更する
クエリ結果が指定された順序にある場合は、簡単にスキャンできます。 返されるシーケンスは、使用可能な任意のフィールドに基づいて並べ替えることができます。
結果を並べ替えるには
Order By
ステートメントとクエリのWhere
ステートメントの間に、次のSelect
句を追加します。Order By
句は、各学生の姓に従って、結果をアルファベット順に A から Z に並べ替えます。Order By currentStudent.Last Ascending
姓、次に名の順に並べるには、両方のフィールドをクエリに追加します。
Order By currentStudent.Last Ascending, currentStudent.First Ascending
Z から A に順序を付ける
Descending
を指定することもできます。Ctrl キーを押しながら F5 キーを押して、アプリケーションをビルドして実行します。 コンソール ウィンドウで結果を確認します。
ローカル識別子を導入するには
このセクションのコードを追加して、クエリ式にローカル識別子を導入します。 ローカル識別子は中間結果を保持します。 次の例では、
name
は、学生の姓と名の連結を保持する識別子です。 便利な目的でローカル識別子を使用することも、それ以外の場合は複数回計算される式の結果を格納することでパフォーマンスを向上させることができます。Dim studentQuery2 = From currentStudent In students Let name = currentStudent.Last & ", " & currentStudent.First Where currentStudent.Year = "Senior" And currentStudent.Rank <= 10 Order By name Ascending Select currentStudent ' If you see too many results, comment out the previous ' For Each loop. For Each studentRecord In studentQuery2 Console.WriteLine(studentRecord.Last & ", " & studentRecord.First) Next
Ctrl キーを押しながら F5 キーを押して、アプリケーションをビルドして実行します。 コンソール ウィンドウで結果を確認します。
Select句で1つのフィールドを投影するには
このセクションからクエリと
For Each
ループを追加して、ソース内の要素と要素が異なるシーケンスを生成するクエリを作成します。 次の例では、ソースはStudent
オブジェクトのコレクションですが、各オブジェクトの 1 つのメンバー (姓が Garcia の学生の名) のみが返されます。currentStudent.First
は文字列であるため、studentQuery3
によって返されるシーケンスのデータ型は、文字列のシーケンスIEnumerable(Of String)
。 前の例と同様に、studentQuery3
のデータ型の割り当ては、ローカル型推論を使用してコンパイラが判断するために残されます。Dim studentQuery3 = From currentStudent In students Where currentStudent.Last = "Garcia" Select currentStudent.First ' If you see too many results, comment out the previous ' For Each loops. For Each studentRecord In studentQuery3 Console.WriteLine(studentRecord) Next
コード内の
studentQuery3
の上にマウス ポインターを置き、割り当てられた型がIEnumerable(Of String)
されていることを確認します。Ctrl キーを押しながら F5 キーを押して、アプリケーションをビルドして実行します。 コンソール ウィンドウで結果を確認します。
Select 句で匿名型を作成するには
このセクションのコードを追加して、クエリで匿名型がどのように使用されているかを確認します。 完全なレコード (前の例ではレコードを
currentStudent
) または単一フィールド (前のセクションのFirst
) ではなく、データ ソースから複数のフィールドを返す場合は、クエリで使用します。 結果に含めるフィールドを含む新しい名前付き型を定義する代わりに、Select
句でフィールドを指定すると、コンパイラはそれらのフィールドをプロパティとして匿名型を作成します。 詳細については、「匿名型」を参照してください。次の例では、学術ランクが 1 から 10 のシニアの名前とランクを、学術的ランク順に返すクエリを作成します。 この例では、
studentQuery4
句は匿名型のインスタンスを返し、匿名型には使用可能な名前がないため、Select
の型を推論する必要があります。Dim studentQuery4 = From currentStudent In students Where currentStudent.Year = "Senior" And currentStudent.Rank <= 10 Order By currentStudent.Rank Ascending Select currentStudent.First, currentStudent.Last, currentStudent.Rank ' If you see too many results, comment out the previous ' For Each loops. For Each studentRecord In studentQuery4 Console.WriteLine(studentRecord.Last & ", " & studentRecord.First & ": " & studentRecord.Rank) Next
Ctrl キーを押しながら F5 キーを押して、アプリケーションをビルドして実行します。 コンソール ウィンドウで結果を確認します。
その他の例
基本について理解したら、LINQ クエリの柔軟性と能力を示す追加の例を次に示します。 各例の前には、その動作の簡単な説明が付きます。 各クエリのクエリ結果変数の上にマウス ポインターを置き、推論された型を確認します。
For Each
ループを使用して結果を生成します。
' Find all students who are seniors.
Dim q1 = From currentStudent In students
Where currentStudent.Year = "Senior"
Select currentStudent
' Write a For Each loop to execute the query.
For Each q In q1
Console.WriteLine(q.First & " " & q.Last)
Next
' Find all students with a first name beginning with "C".
Dim q2 = From currentStudent In students
Where currentStudent.First.StartsWith("C")
Select currentStudent
' Find all top ranked seniors (rank < 40).
Dim q3 = From currentStudent In students
Where currentStudent.Rank < 40 And currentStudent.Year = "Senior"
Select currentStudent
' Find all seniors with a lower rank than a student who
' is not a senior.
Dim q4 = From student1 In students, student2 In students
Where student1.Year = "Senior" And student2.Year <> "Senior" And
student1.Rank > student2.Rank
Select student1
Distinct
' Retrieve the full names of all students, sorted by last name.
Dim q5 = From currentStudent In students
Order By currentStudent.Last
Select Name = currentStudent.First & " " & currentStudent.Last
' Determine how many students are ranked in the top 20.
Dim q6 = Aggregate currentStudent In students
Where currentStudent.Rank <= 20
Into Count()
' Count the number of different last names in the group of students.
Dim q7 = Aggregate currentStudent In students
Select currentStudent.Last
Distinct
Into Count()
' Create a list box to show the last names of students.
Dim lb As New System.Windows.Forms.ListBox
Dim q8 = From currentStudent In students
Order By currentStudent.Last
Select currentStudent.Last Distinct
For Each nextName As String In q8
lb.Items.Add(nextName)
Next
' Find every process that has a lowercase "h", "l", or "d" in its name.
Dim letters() As String = {"h", "l", "d"}
Dim q9 = From proc In System.Diagnostics.Process.GetProcesses,
letter In letters
Where proc.ProcessName.Contains(letter)
Select proc
For Each proc In q9
Console.WriteLine(proc.ProcessName & ", " & proc.WorkingSet64)
Next
追加情報
クエリの操作の基本的な概念を理解したら、関心のある特定の種類の LINQ プロバイダーのドキュメントとサンプルを読む準備ができました。
こちらも参照ください
.NET