更新日: 2010 年 5 月 21 日
この記事は、「MSDN プログラミング シリーズ」として発行している技術書籍「ステップアップ Visual Basic 2010 ~開発者がもう一歩上達するための必読アドバイス」(日経 BP 社刊) を基に先進的なテクニックを紹介しています。
目次
1. はじめに
この一連の記事では、統合言語クエリ (LINQ: Language-Integrated Query) の理解を深めるための関連知識として、ジェネリックや拡張メソッド、ラムダ式について取り上げました。そして、今回から 4 回に渡り、いよいよ、これまで説明した知識をベースとして、LINQ の構文や関連するライブラリについて解説します。(これまでに説明した「型推論」、「匿名型」、「拡張メソッド」、「ラムダ式」などの概念を理解した上で、読み進めてください。)
そもそも、LINQ とは様々な種類の異なるデータに一様な方法でアクセスするためのテクノロジです。その実体は、Visual Basic の構文やライブラリとして提供されます。これらの中で、今回は、構文としての基本事項を改めて振り返り、それに関連する注意点などについて取り上げます。
今後は LINQ を使う機会もますます増えて来ることでしょう。今のうちに、しっかりマスターしておきましょう。
2. 基本的なクエリ式
まず、データソースに対してクエリを行う「クエリ式」の書き方について取り上げます。基本的なクエリ式にも様々なバリエーションがあり、一部を見落としてしまうことがあるかも知れません。この点もふまえ、基本的な構文を改めて確認してみましょう。
次の例 1 は基本的なクエリ式を使用した例です。(このサンプルコードを実行するには、Windows フォームアプリケーションを作成し、フォームに 1 つのボタンと 1 つのリストボックスを貼り付けた後、このサンプルコードと同じになるよう修正や追加を行ってください。)
例 1. 基本的なクエリ式
Public Class Form1
Private Sub Button1_Click(...) Handles Button1.Click ←Clickイベントハンドラ
Dim data() As Integer = {200,500,100,300,600,400} ←[1]
Dim query1 =From d In data Where d <= 300 Select d←[2]
For Each d As Integer In query1 ←[3]
ListBox1.Items.Add(d)
Next
End Sub
End Class
ここでは簡単にするため、[1] に定義された Integer 型の配列 data に対して、クエリ操作を行います。[2] の太字部分が、この配列に対してクエリ操作を行うクエリ式です。ここでは、値が 300 以下の要素を抽出しています。クエリ式は、文字通り「抽出結果という値を求める式」であり、式自体が値を表すので、[2] にあるように変数 (ここでは変数 query1) に代入できます。
このクエリ式が返す結果を代入した変数は「クエリ変数」と呼ばれています。論理的には、クエリ変数はクエリ結果 (抽出結果の要素集合) とみなすことができます。しかし、厳密にいうと、実は、クエリ変数にクエリ式を代入しただけでは (上記の [2] を実行しただけでは)、実際のクエリ操作は実行されていません。いつ実行されるかは、データソースやクエリ式の書き方に依存しますが、一般に LINQ では実際に要素を参照するまではクエリ操作が保留されます。これを「遅延実行」と呼びます。この例でも、クエリの書き方によって実行のタイミングが若干異なるのですが、少なくも [3] の For Each ループを使用してクエリ結果 (クエリ変数) から実際に要素を参照するまでは、クエリが実行されないと考えておいてください。
また Visual Basic では、原則として 1 つの式や 1 つのステートメントを書くとき、途中で改行せずに 1 行に書く必要がありますが (改行をおこなうには _ (アンダーバー) を使用する必要がありますが)、Visual Basic 2010 の新機能として、行の継続が想定されるいくつかの構文では、途中改行が認められるようになりました。よって、次の例 2 のようにクエリ式を 2 行に渡って記述しても有効な構文となります (1 行目の末尾に継続を表す記号である「アンダーバー」を書く必要はありません)。特にクエリ式は長くなりがちです。このような自然な改行によって、可読性も向上するでしょう。
例 2. クエリ式の暗黙的な行継続 (Visual Basic 2010 から)
Where d <= 300 Select d
次に、このクエリ式の意味を考えてみましょう。
クエリ操作の対象となるデータソース (データの集合) は、In キーワードの後ろに記述されます。また、その集合の要素 1 つを表す変数定義が d になります。よって、次のような For Each ループと同じ構造と考えてよいでしょう。
ForEachdIndata
この変数 d はクエリ式の中だけで利用されるローカル変数であり、Where キーワード以降で使用されています。そして、Where 句には抽出条件を書き (ここでは要素 d が 300 以下)、Select 句には抽出した要素の形式を指定します。
Select 句では上記の例のように単に「Select d」と書けば、元の要素の形のままとなり、抽出結果は、200、100、および 300 という値の集合となります。ただし、構文として有効な式であれば何でも書けるので、次のように書くことも可能です。