初めての LINQ クエリの作成 (Visual Basic)Writing Your First LINQ Query (Visual Basic)

"クエリ" は、データ ソースからデータを取得する式です。A query is an expression that retrieves data from a data source. クエリは、専用のクエリ言語で表されます。Queries are expressed in a dedicated query language. これまでに、リレーショナル データベース用の SQL や XML 用の XQuery など、各種データ ソースに合わせてさまざまな言語が開発されてきました。Over time, different languages have been developed for different types of data sources, for example, SQL for relational databases and XQuery for XML. このため、アプリケーション開発者は、サポートするデータ ソースの種類やデータ形式ごとに、新しいクエリ言語を習得する必要がありました。This makes it necessary for the application developer to learn a new query language for each type of data source or data format that is supported.

統合言語クエリ (LINQ) は、さまざまな種類のデータ ソースやデータ形式のデータを操作するための一貫したモデルを提供することにより、この負担を軽減します。Language-Integrated Query (LINQ) simplifies the situation by offering a consistent model for working with data across various kinds of data sources and formats. LINQ クエリでは、操作の対象は常にオブジェクトになります。In a LINQ query, you are always working with objects. 共通の基本的なコーディング パターンを使用することで、XML ドキュメント、SQL データベース、ADO.NET データセットおよびエンティティ、.NET Framework のコレクションなど、LINQ プロバイダーを利用できるあらゆるソースまたは形式のデータを照会したり変換したりすることができます。You use the same basic coding patterns to query and transform data in XML documents, SQL databases, ADO.NET datasets and entities, .NET Framework collections, and any other source or format for which a LINQ provider is available. このドキュメントでは、基本的な LINQ クエリの作成と使用の 3 つのフェーズについて説明しています。This document describes the three phases of the creation and use of basic LINQ queries.

クエリ操作の 3 つのステージThree Stages of a Query Operation

LINQ クエリ操作はすべて、次の 3 つのアクションで構成されます。LINQ query operations consist of three actions:

  1. データ ソースまたはソースを取得します。Obtain the data source or sources.

  2. クエリを作成します。Create the query.

  3. クエリを実行します。Execute the query.

LINQ では、クエリの実行とクエリの作成が区別されます。In LINQ, the execution of a query is distinct from the creation of the query. クエリを作成するだけでは、データは取得されません。You do not retrieve any data just by creating a query. この点については、後で詳しく説明します。This point is discussed in more detail later in this topic.

以下の例は、クエリ操作を構成する 3 つの要素を示しています。The following example illustrates the three parts of a query operation. この例では、デモンストレーション用に便利なデータ ソースとして整数の配列を使用しています。The example uses an array of integers as a convenient data source for demonstration purposes. ただし同じ概念は、他のデータ ソースにも当てはまります。However, the same concepts also apply to other data sources.

注意

プロジェクト デザイナー (Visual Basic) の [コンパイル] ページで、 [Option infer][On] に設定されていることを確認します。On the Compile Page, Project Designer (Visual Basic), ensure that Option infer is set to On.

' Data source.
Dim numbers() As Integer = {0, 1, 2, 3, 4, 5, 6}

' Query creation.
Dim evensQuery = From num In numbers
                 Where num Mod 2 = 0
                 Select num

' Query execution.
For Each number In evensQuery
    Console.Write(number & " ")
Next

Output:Output:

0 2 4 6

データ ソースThe Data Source

前の例では、データ ソースが配列であるため、暗黙的にジェネリック IEnumerable<T> インターフェイスがサポートされます。Because the data source in the previous example is an array, it implicitly supports the generic IEnumerable<T> interface. 配列を LINQ クエリのデータ ソースとして使用できるのは、そのためです。It is this fact that enables you to use an array as a data source for a LINQ query. IEnumerable<T> をサポートする型や、ジェネリック IQueryable<T> などの派生インターフェイスは、クエリ可能型と呼ばれます。Types that support IEnumerable<T> or a derived interface such as the generic IQueryable<T> are called queryable types.

配列は、暗黙的なクエリ可能型として、変更や特別な処理を行わなくても、LINQ データ ソースとして使用できます。As an implicitly queryable type, the array requires no modification or special treatment to serve as a LINQ data source. 同じことは、ジェネリックである List<T>Dictionary<TKey,TValue>、その他 .NET Framework クラス ライブラリのクラスなど、IEnumerable<T> をサポートするすべてのコレクション型に言えます。The same is true for any collection type that supports IEnumerable<T>, including the generic List<T>, Dictionary<TKey,TValue>, and other classes in the .NET Framework class library.

ソース データにまだ IEnumerable<T> が実装されていない場合、そのデータ ソースに "標準クエリ演算子" の機能を実装するためには、LINQ プロバイダーが必要となります。If the source data does not already implement IEnumerable<T>, a LINQ provider is needed to implement the functionality of the standard query operators for that data source. たとえば、LINQ to XMLLINQ to XML は、XML ドキュメントを、クエリ可能な XElement 型に読み込む処理を担います (以下の例を参照)。For example, LINQ to XMLLINQ to XML handles the work of loading an XML document into a queryable XElement type, as shown in the following example. 標準クエリ演算子について詳しくは、「標準クエリ演算子の概要 (Visual Basic)」を参照してください。For more information about standard query operators, see Standard Query Operators Overview (Visual Basic).

' Create a data source from an XML document.
Dim contacts = XElement.Load("c:\myContactList.xml")

LINQ to SQLLINQ to SQL では、まず、デザイン時に手動で、または Visual Studioで Visual Studio の LINQ to SQL ツールを使用して、オブジェクト リレーショナル マッピングを作成します。With LINQ to SQLLINQ to SQL, you first create an object-relational mapping at design time, either manually or by using the LINQ to SQL Tools in Visual Studio in Visual Studio. オブジェクトに対するクエリを記述すると、実行時には、LINQ to SQLLINQ to SQL によってデータベースとの通信が処理されます。You write your queries against the objects, and at run-time LINQ to SQLLINQ to SQL handles the communication with the database. 次の例の customers は、データベース内の特定のテーブルを表し、Table<TEntity> はジェネリックの IQueryable<T> をサポートします。In the following example, customers represents a specific table in the database, and Table<TEntity> supports generic IQueryable<T>.

' Create a data source from a SQL table.  
Dim db As New DataContext("C:\Northwind\Northwnd.mdf")  
Dim customers As Table(Of Customer) = db.GetTable(Of Customer)  

それぞれの種類のデータ ソースを作成する方法の詳細については、対応する LINQ プロバイダーのドキュメントを参照してください。For more information about how to create specific types of data sources, see the documentation for the various LINQ providers. (該当するプロバイダーの一覧については、LINQ (統合言語クエリ) に関するページを参照してください)。基本的な規則は単純です。LINQ データ ソースは、ジェネリック IEnumerable<T> インターフェイスか、これを継承するインターフェイスをサポートする任意のオブジェクトです。(For a list of these providers, see LINQ (Language-Integrated Query).) The basic rule is simple: a LINQ data source is any object that supports the generic IEnumerable<T> interface, or an interface that inherits from it.

注意

非ジェネリック IEnumerable インターフェイスをサポートする ArrayList などの型も、LINQ データ ソースとして使用できます。Types such as ArrayList that support the non-generic IEnumerable interface can also be used as LINQ data sources. ArrayList の使用例については、「方法: LINQ を使用して ArrayList を照会する (Visual Basic)」を参照してください。For an example that uses an ArrayList, see How to: Query an ArrayList with LINQ (Visual Basic).

クエリThe Query

クエリには、データ ソースまたはソースから取得したい情報を指定します。In the query, you specify what information you want to retrieve from the data source or sources. また、どのように情報を並べ替え、グループ化、または構造化して返されるようにするかをオプションで指定することもできます。You also have the option of specifying how that information should be sorted, grouped, or structured before it is returned. Visual Basic 言語には、クエリの作成に対応するために、新しいクエリ構文が導入されています。To enable query creation, Visual Basic has incorporated new query syntax into the language.

次の例のクエリを実行すると、整数の配列 numbers からすべての偶数が返されます。When it is executed, the query in the following example returns all the even numbers from an integer array, numbers.

' Data source.
Dim numbers() As Integer = {0, 1, 2, 3, 4, 5, 6}

' Query creation.
Dim evensQuery = From num In numbers
                 Where num Mod 2 = 0
                 Select num

' Query execution.
For Each number In evensQuery
    Console.Write(number & " ")
Next

このクエリ式には、FromWhereSelect の 3 つの句が含まれています。The query expression contains three clauses: From, Where, and Select. クエリ式の各句の具体的な関数と目的は、「基本的なクエリ操作 (Visual Basic)」で説明しています。The specific function and purpose of each query expression clause is discussed in Basic Query Operations (Visual Basic). 詳細については、「クエリ」を参照してください。For more information, see Queries. LINQ では多くの場合、クエリの定義はまず変数に格納され、その後実行されます。Note that in LINQ, a query definition often is stored in a variable and executed later. 前の例の evensQuery のように、クエリ変数はクエリ可能型であることが必要です。The query variable, such as evensQuery in the previous example, must be a queryable type. evensQuery の型は IEnumerable(Of Integer) で、コンパイラによってローカル型推論を使用して割り当てられます。The type of evensQuery is IEnumerable(Of Integer), assigned by the compiler using local type inference.

クエリ変数自体は何も処理を行わず、データを返さないという点に注意してください。It is important to remember that the query variable itself takes no action and returns no data. あくまでクエリの定義が格納されるだけです。It only stores the query definition. 前の例で、クエリを実行するのは For Each ループです。In the previous example, it is the For Each loop that executes the query.

クエリの実行Query Execution

クエリの実行とクエリの作成は分離しています。Query execution is separate from query creation. クエリを作成することによってクエリは定義されますが、その実行をトリガーするのは別のメカニズムになります。Query creation defines the query, but execution is triggered by a different mechanism. クエリは、定義後すぐに実行 ("即時実行)" することも、定義を保存しておき、後でクエリを実行 ("遅延実行") することもできます。A query can be executed as soon as it is defined (immediate execution), or the definition can be stored and the query can be executed later (deferred execution).

遅延実行Deferred Execution

一般的な LINQ クエリは、前の例のようなものです。前の例には evensQuery が定義されています。A typical LINQ query resembles the one in the previous example, in which evensQuery is defined. クエリは作成されても、すぐには実行されません。It creates the query but does not execute it immediately. その代わりに、クエリ変数 evensQuery にクエリの定義が格納されます。Instead, the query definition is stored in the query variable evensQuery. 通常は、一連の値を返す For Each ループを使用するか、標準クエリ演算子 (CountMax など) を適用することによって、クエリを後から実行することになります。You execute the query later, typically by using a For Each loop, which returns a sequence of values, or by applying a standard query operator, such as Count or Max. この処理を "遅延実行" と呼びます。This process is referred to as deferred execution.

' Query execution that results in a sequence of values.
For Each number In evensQuery
    Console.Write(number & " ")
Next

' Query execution that results in a single value.
Dim evens = evensQuery.Count()

一連の値を得るには、For Each ループの反復変数 (前の例では number) を使用して、取得したデータにアクセスします。For a sequence of values, you access the retrieved data by using the iteration variable in the For Each loop (number in the previous example). クエリ変数 evensQuery が保持するのはクエリの結果ではなくクエリの定義であるため、繰り返しクエリ変数を使用することで、必要に応じて何度でもクエリを実行できます。Because the query variable, evensQuery, holds the query definition rather than the query results, you can execute a query as often as you want by using the query variable more than one time. たとえばアプリケーションに使用しているデータベースが、別のアプリケーションによって絶えず更新されているとします。For example, you might have a database in your application that is being updated continually by a separate application. データベースからデータを取得するクエリを作成しておき、For Each ループを使用して繰り返しクエリを実行すれば、毎回最新のデータを取得できます。After you have created a query that retrieves data from that database, you can use a For Each loop to execute the query repeatedly, retrieving the most recent data every time.

以下の例は、遅延実行の動作を示したものです。The following example demonstrates how deferred execution works. まず、前の例のように evensQuery2 を定義し、For Each ループで実行した後、データ ソース numbers 内のいくつかの要素に変更を加えています。After evensQuery2 is defined and executed with a For Each loop, as in the previous examples, some elements in the data source numbers are changed. その後、2 つ目の For Each ループで evensQuery2 を再実行します。Then a second For Each loop runs evensQuery2 again. For Each ループでクエリを再実行するときは、numbers 内の新しい値が使用されるため、2 回目は異なる結果が得られます。The results are different the second time, because the For Each loop executes the query again, using the new values in numbers.

Dim numberArray() = {0, 1, 2, 3, 4, 5, 6}

Dim evensQuery2 = From num In numberArray
                  Where num Mod 2 = 0
                  Select num

Console.WriteLine("Evens in original array:")
For Each number In evensQuery2
    Console.Write("  " & number)
Next
Console.WriteLine()

' Change a few array elements.
numberArray(1) = 10
numberArray(4) = 22
numberArray(6) = 8

' Run the same query again.
Console.WriteLine(vbCrLf & "Evens in changed array:")
For Each number In evensQuery2
    Console.Write("  " & number)
Next
Console.WriteLine()

Output:Output:

Evens in original array:

0 2 4 6

Evens in changed array:

0 10 2 22 8

即時実行Immediate Execution

クエリの遅延実行では、クエリの定義がクエリ変数に格納され、後から実行されます。In deferred execution of queries, the query definition is stored in a query variable for later execution. 即時実行では、クエリがその定義時に実行されます。In immediate execution, the query is executed at the time of its definition. クエリ結果の個々の要素にアクセスする必要があるメソッドを適用したときに、実行がトリガーされます。Execution is triggered when you apply a method that requires access to individual elements of the query result. 即時実行は多くの場合、単一の値を返すいずれかの標準クエリ演算子を使用することで強制的に発生します。Immediate execution often is forced by using one of the standard query operators that return single values. たとえば、CountMaxAverageFirst が該当します。Examples are Count, Max, Average, and First. これらの標準クエリ演算子では、シングルトンの結果を算出して返すために、適用された時点ですぐにクエリが実行されます。These standard query operators execute the query as soon as they are applied in order to calculate and return a singleton result. 単一の値を返す標準クエリ演算子の詳細については、「集計操作」、「要素の操作」、「量指定子操作」を参照してください。For more information about standard query operators that return single values, see Aggregation Operations, Element Operations, and Quantifier Operations.

次のクエリからは、整数の配列に格納されている偶数の数が返されます。The following query returns a count of the even numbers in an array of integers. クエリの定義は保存されません。numEvens は単純な Integer です。The query definition is not saved, and numEvens is a simple Integer.

Dim numEvens = (From num In numbers
                Where num Mod 2 = 0
                Select num).Count()

同じ結果は、Aggregate メソッドを使用して取得することもできます。You can achieve the same result by using the Aggregate method.

Dim numEvensAgg = Aggregate num In numbers
                  Where num Mod 2 = 0
                  Select num
                  Into Count()

次のコードに示すとおり、クエリ (即時) またはクエリ変数 (遅延) の ToList メソッドまたは ToArray メソッドを呼び出すことによって、クエリの実行を強制することもできます。You can also force execution of a query by calling the ToList or ToArray method on a query (immediate) or query variable (deferred), as shown in the following code.

' Immediate execution.
Dim evensList = (From num In numbers
                 Where num Mod 2 = 0
                 Select num).ToList()

' Deferred execution.
Dim evensQuery3 = From num In numbers
                  Where num Mod 2 = 0
                  Select num
' . . .
Dim evensArray = evensQuery3.ToArray()

前の例で、evensQuery3 はクエリ変数ですが、evensList はリストで、evensArray は配列です。In the previous examples, evensQuery3 is a query variable, but evensList is a list and evensArray is an array.

ToList または ToArray を使用して即時実行を強制する手法は、クエリを直ちに実行してその結果を単一のコレクション オブジェクトにキャッシュしておくようなシナリオで特に便利です。Using ToList or ToArray to force immediate execution is especially useful in scenarios in which you want to execute the query immediately and cache the results in a single collection object. これらのメソッドの詳細については、「データ型の変換」を参照してください。For more information about these methods, see Converting Data Types.

また、IEnumerable メソッド (IEnumerable.GetEnumerator メソッドなど) を使用してクエリの実行を生じさせることもできます。You can also cause a query to be executed by using an IEnumerable method such as the IEnumerable.GetEnumerator method.

関連項目See also