Language-Integrated クエリ (LINQ) は、Visual Basic にクエリ機能を追加し、あらゆる種類のデータを操作する際にシンプルで強力な機能を提供します。 処理するデータベースにクエリを送信したり、検索するデータの種類ごとに異なるクエリ構文を操作したりする代わりに、LINQ では Visual Basic 言語の一部としてクエリが導入されます。 データの種類に関係なく、統一された構文が使用されます。
LINQ を使用すると、SQL Server データベース、XML、インメモリ配列とコレクション、ADO.NET データセット、または LINQ をサポートするその他のリモートまたはローカル データ ソースからのデータに対してクエリを実行できます。 この操作はすべて、一般的な Visual Basic 言語要素を使用して行うことができます。 クエリは Visual Basic 言語で記述されるため、クエリ結果は厳密に型指定されたオブジェクトとして返されます。 これらのオブジェクトは IntelliSense をサポートしています。これにより、実行時ではなくコンパイル時にコードをより高速に記述し、クエリでエラーをキャッチできます。 LINQ クエリは、結果を絞り込むための追加クエリのソースとして使用できます。 また、ユーザーがクエリ結果を簡単に表示および変更できるように、コントロールにバインドすることもできます。
たとえば、次のコード例は、コレクションから顧客の一覧を返し、その場所に基づいてグループ化する LINQ クエリを示しています。
' Obtain a list of customers.
Dim customers As List(Of Customer) = GetCustomers()
' Return customers that are grouped based on country.
Dim countries = From cust In customers
Order By cust.Country, cust.City
Group By CountryName = cust.Country
Into CustomersInCountry = Group, Count()
Order By CountryName
' Output the results.
For Each country In countries
Debug.WriteLine(country.CountryName & " count=" & country.Count)
For Each customer In country.CustomersInCountry
Debug.WriteLine(" " & customer.CompanyName & " " & customer.City)
Next
Next
' Output:
' Canada count=2
' Contoso, Ltd Halifax
' Fabrikam, Inc. Vancouver
' United States count=1
' Margie's Travel Redmond
例を実行する
概要セクションと LINQ クエリの構造 セクションの例を実行するには、顧客と注文の一覧を返す次のコードを含めます。
' Return a list of customers.
Private Function GetCustomers() As List(Of Customer)
Return New List(Of Customer) From
{
New Customer With {.CustomerID = 1, .CompanyName = "Contoso, Ltd", .City = "Halifax", .Country = "Canada"},
New Customer With {.CustomerID = 2, .CompanyName = "Margie's Travel", .City = "Redmond", .Country = "United States"},
New Customer With {.CustomerID = 3, .CompanyName = "Fabrikam, Inc.", .City = "Vancouver", .Country = "Canada"}
}
End Function
' Return a list of orders.
Private Function GetOrders() As List(Of Order)
Return New List(Of Order) From
{
New Order With {.CustomerID = 1, .Amount = "200.00"},
New Order With {.CustomerID = 3, .Amount = "600.00"},
New Order With {.CustomerID = 1, .Amount = "300.00"},
New Order With {.CustomerID = 2, .Amount = "100.00"},
New Order With {.CustomerID = 3, .Amount = "800.00"}
}
End Function
' Customer Class.
Private Class Customer
Public Property CustomerID As Integer
Public Property CompanyName As String
Public Property City As String
Public Property Country As String
End Class
' Order Class.
Private Class Order
Public Property CustomerID As Integer
Public Property Amount As Decimal
End Class
LINQ プロバイダー
LINQ プロバイダーは、クエリ対象のデータ ソースに Visual Basic LINQ クエリをマップします。 LINQ クエリを記述すると、プロバイダーはそのクエリを受け取り、データ ソースが実行できるコマンドに変換します。 プロバイダーは、ソースからクエリ結果を構成するオブジェクトにデータを変換します。 最後に、データ ソースに更新を送信すると、オブジェクトがデータに変換されます。
Visual Basic には、次の LINQ プロバイダーが含まれています。
プロバイダー | 説明 |
---|---|
LINQ to Objects | LINQ to Objects プロバイダーを使用すると、メモリ内のコレクションと配列に対してクエリを実行できます。 オブジェクトが IEnumerable または IEnumerable<T> インターフェイスのいずれかをサポートしている場合、LINQ to Objects プロバイダーを使用すると、クエリを実行できます。 LINQ to Objects プロバイダーを有効にするには、すべての Visual Basic プロジェクトに対して既定でインポートされる System.Linq 名前空間をインポートします。 LINQ to Objects プロバイダーの詳細については、「 LINQ to Objects」を参照してください。 |
LINQ to SQL | LINQ to SQL プロバイダーを使用すると、SQL Server データベース内のデータのクエリと変更を行うことができます。 これにより、アプリケーションのオブジェクト モデルをデータベース内のテーブルとオブジェクトに簡単にマップできます。 Visual Basic では、オブジェクト リレーショナル デザイナー (O/R デザイナー) を含めることで LINQ to SQL を簡単に操作できます。 このデザイナーは、データベース内のオブジェクトにマップするオブジェクト モデルをアプリケーションで作成するために使用されます。 O/R デザイナーには、ストアド プロシージャと関数を DataContext オブジェクトにマップする機能も用意されています。このオブジェクトは、データベースとの通信を管理し、オプティミスティック コンカレンシー チェックの状態を格納します。 LINQ to SQL プロバイダーの詳細については、「 LINQ to SQL」を参照してください。 オブジェクト リレーショナル デザイナーの詳細については、「 Visual Studio の LINQ to SQL Tools」を参照してください。 |
LINQ to XML | LINQ to XML プロバイダーを使用すると、XML のクエリと変更を行います。 インメモリ XML を変更することも、XML をファイルから読み込んでファイルに保存することもできます。 さらに、LINQ to XML プロバイダーを使用すると、XML リテラルと XML 軸プロパティを使用して、Visual Basic コードで XML を直接記述できます。 詳細については、 XML を参照してください。 |
LINQ to DataSet | LINQ to DataSet プロバイダーを使用すると、ADO.NET データセット内のデータのクエリと更新を実行できます。 データセットを使用する LINQ to アプリケーションの機能を追加して、データセット内のデータのクエリ、集計、更新の機能を簡素化および拡張できます。 詳細については、「 LINQ to DataSet」を参照してください。 |
LINQ クエリの構造
LINQ クエリは、クエリ式と呼ばれることが多く、 クエリのデータ ソースと反復変数を識別するクエリ句の組み合わせで構成されます。 クエリ式には、ソース データに適用する並べ替え、フィルター処理、グループ化、結合、計算の手順を含めることもできます。 クエリ式の構文は SQL の構文に似ています。そのため、構文の多くは使い慣れている場合があります。
クエリ式は、 From
句で始まります。 この句は、クエリのソース データと、ソース データの各要素を個別に参照するために使用される変数を識別します。 これらの変数は、名前付き 範囲変数 または 反復変数です。
From
句が省略可能なAggregate
クエリを除き、クエリには From
句が必要です。 クエリのスコープとソースが From
句または Aggregate
句で識別されたら、クエリ句の任意の組み合わせを含めてクエリを絞り込むことができます。 クエリ句の詳細については、このトピックで後述する「Visual Basic LINQ クエリ演算子」を参照してください。 たとえば、次のクエリでは、 customers
変数として顧客データのソース コレクションと、 cust
という名前の反復変数を識別します。
Dim customers = GetCustomers()
Dim queryResults = From cust In customers
For Each result In queryResults
Debug.WriteLine(result.CompanyName & " " & result.Country)
Next
' Output:
' Contoso, Ltd Canada
' Margie's Travel United States
' Fabrikam, Inc. Canada
この例は、単独で有効なクエリです。ただし、クエリ句を追加して結果を絞り込むと、クエリがはるかに強力になります。 たとえば、 Where
句を追加して、1 つ以上の値で結果をフィルター処理できます。 クエリ式は 1 行のコードです。クエリの末尾に追加のクエリ句を追加するだけです。 アンダースコア (_) 行連結文字を使用して、複数行のテキストに対してクエリを分割して読みやすくすることができます。 次のコード例は、 Where
句を含むクエリの例を示しています。
Dim queryResults = From cust In customers
Where cust.Country = "Canada"
もう 1 つの強力なクエリ句は Select
句です。これにより、データ ソースから選択したフィールドのみを返します。 LINQ クエリは、厳密に型指定されたオブジェクトの列挙可能なコレクションを返します。 クエリは、匿名型または名前付き型のコレクションを返すことができます。
Select
句を使用すると、データ ソースから 1 つのフィールドのみを返すことができます。 これを行うと、返されるコレクションの型は、その 1 つのフィールドの型になります。
Select
句を使用して、データ ソースから複数のフィールドを返すこともできます。 これを行うと、返されるコレクションの型は新しい匿名型になります。 また、クエリによって返されるフィールドを、指定した名前付き型のフィールドと照合することもできます。 次のコード例は、メンバーにデータ ソースから選択されたフィールドのデータが設定された匿名型のコレクションを返すクエリ式を示しています。
Dim queryResults = From cust In customers
Where cust.Country = "Canada"
Select cust.CompanyName, cust.Country
LINQ クエリを使用して、複数のデータ ソースを結合し、1 つの結果を返すこともできます。 これを行うには、1 つ以上の From
句を使用するか、 Join
または Group Join
クエリ句を使用します。 次のコード例は、顧客データと注文データを組み合わせ、顧客データと注文データを含む匿名型のコレクションを返すクエリ式を示しています。
Dim customers = GetCustomers()
Dim orders = GetOrders()
Dim queryResults = From cust In customers, ord In orders
Where cust.CustomerID = ord.CustomerID
Select cust, ord
For Each result In queryResults
Debug.WriteLine(result.ord.Amount & " " & result.ord.CustomerID & " " & result.cust.CompanyName)
Next
' Output:
' 200.00 1 Contoso, Ltd
' 300.00 1 Contoso, Ltd
' 100.00 2 Margie's Travel
' 600.00 3 Fabrikam, Inc.
' 800.00 3 Fabrikam, Inc.
Group Join
句を使用して、顧客オブジェクトのコレクションを含む階層クエリ結果を作成できます。 各顧客オブジェクトには、その顧客のすべての注文のコレクションを含むプロパティがあります。 次のコード例は、顧客データと注文データを階層的な結果として結合し、匿名型のコレクションを返すクエリ式を示しています。 クエリは、顧客の注文データのコレクションを含む CustomerOrders
プロパティを含む型を返します。 また、その顧客のすべての注文の合計を含む OrderTotal
プロパティも含まれます。 (このクエリは LEFT OUTER JOIN と同じです)。
Dim customers = GetCustomers()
Dim orders = GetOrders()
Dim queryResults = From cust In customers
Group Join ord In orders On
cust.CustomerID Equals ord.CustomerID
Into CustomerOrders = Group,
OrderTotal = Sum(ord.Amount)
Select cust.CompanyName, cust.CustomerID,
CustomerOrders, OrderTotal
For Each result In queryResults
Debug.WriteLine(result.OrderTotal & " " & result.CustomerID & " " & result.CompanyName)
For Each ordResult In result.CustomerOrders
Debug.WriteLine(" " & ordResult.Amount)
Next
Next
' Output:
' 500.00 1 Contoso, Ltd
' 200.00
' 300.00
' 100.00 2 Margie's Travel
' 100.00
' 1400.00 3 Fabrikam, Inc.
' 600.00
' 800.00
強力なクエリ式を作成するために使用できる LINQ クエリ演算子がいくつかあります。 このトピックの次のセクションでは、クエリ式に含めることができるさまざまなクエリ句について説明します。 Visual Basic クエリ句の詳細については、「 クエリ」を参照してください。
Visual Basic LINQ クエリ演算子
System.Linq名前空間のクラスと、LINQ クエリをサポートするその他の名前空間には、アプリケーションのニーズに基づいてクエリを作成および調整するために呼び出すことができるメソッドが含まれています。 Visual Basic には、次の一般的なクエリ句のキーワードが含まれています。 Visual Basic クエリ句の詳細については、「 クエリ」を参照してください。
From 句
クエリを開始するには、From
句または Aggregate
句が必要です。
From
句は、クエリのソース コレクションと反復変数を指定します。 例えば次が挙げられます。
' Returns the company name for all customers for which
' the Country is equal to "Canada".
Dim names = From cust In customers
Where cust.Country = "Canada"
Select cust.CompanyName
Select 句
任意。
Select
句は、クエリの反復変数のセットを宣言します。 例えば次が挙げられます。
' Returns the company name and ID value for each
' customer as a collection of a new anonymous type.
Dim customerList = From cust In customers
Select cust.CompanyName, cust.CustomerID
Select
句が指定されていない場合、クエリの反復変数は、From
句または Aggregate
句で指定された反復変数で構成されます。
Where 句
任意。
Where
句は、クエリのフィルター条件を指定します。 例えば次が挙げられます。
' Returns all product names for which the Category of
' the product is "Beverages".
Dim names = From product In products
Where product.Category = "Beverages"
Select product.Name
Order By 句
任意。
Order By
句は、クエリ内の列の並べ替え順序を指定します。 例えば次が挙げられます。
' Returns a list of books sorted by price in
' ascending order.
Dim titlesAscendingPrice = From b In books
Order By b.price
Join 句
任意。
Join
句は、2 つのコレクションを 1 つのコレクションに結合します。 例えば次が挙げられます。
' Returns a combined collection of all of the
' processes currently running and a descriptive
' name for the process taken from a list of
' descriptive names.
Dim processes = From proc In Process.GetProcesses
Join desc In processDescriptions
On proc.ProcessName Equals desc.ProcessName
Select proc.ProcessName, proc.Id, desc.Description
Group By 句
任意。
Group By
句は、クエリ結果の要素をグループ化します。 各グループに集計関数を適用するために使用できます。 例えば次が挙げられます。
' Returns a list of orders grouped by the order date
' and sorted in ascending order by the order date.
Dim orderList = From order In orders
Order By order.OrderDate
Group By OrderDate = order.OrderDate
Into OrdersByDate = Group
Group Join 句
任意。
Group Join
句は、2 つのコレクションを 1 つの階層コレクションに結合します。 例えば次が挙げられます。
' Returns a combined collection of customers and
' customer orders.
Dim customerList = From cust In customers
Group Join ord In orders On
cust.CustomerID Equals ord.CustomerID
Into CustomerOrders = Group,
TotalOfOrders = Sum(ord.Amount)
Select cust.CompanyName, cust.CustomerID,
CustomerOrders, TotalOfOrders
Aggregate 句
クエリを開始するには、 Aggregate
句 または From
句が必要です。
Aggregate
句は、1 つ以上の集計関数をコレクションに適用します。 たとえば、次の例のように、 Aggregate
句を使用して、クエリによって返されるすべての要素の合計を計算できます。
' Returns the sum of all order amounts.
Dim orderTotal = Aggregate order In orders
Into Sum(order.Amount)
Aggregate
句を使用してクエリを変更することもできます。 たとえば、 Aggregate
句を使用して、関連するクエリ コレクションに対して計算を実行できます。 例えば次が挙げられます。
' Returns the customer company name and largest
' order amount for each customer.
Dim customerMax = From cust In customers
Aggregate order In cust.Orders
Into MaxOrder = Max(order.Amount)
Select cust.CompanyName, MaxOrder
Let 句
任意。
Let
句は、値を計算し、クエリの新しい変数に割り当てます。 例えば次が挙げられます。
' Returns a list of products with a calculation of
' a ten percent discount.
Dim discountedProducts = From prod In products
Let Discount = prod.UnitPrice * 0.1
Where Discount >= 50
Select prod.Name, prod.UnitPrice, Discount
Distinct 句
任意。
Distinct
句は、クエリ結果の重複する値を排除するために、現在の反復変数の値を制限します。 例えば次が挙げられます。
' Returns a list of cities with no duplicate entries.
Dim cities = From item In customers
Select item.City
Distinct
Skip 句
任意。
Skip
句は、コレクション内の指定された数の要素をバイパスし、残りの要素を返します。 例えば次が挙げられます。
' Returns a list of customers. The first 10 customers
' are ignored and the remaining customers are
' returned.
Dim customerList = From cust In customers
Skip 10
Skip While 句
任意。
Skip While
句は、指定した条件がtrue
されている限り、コレクション内の要素をバイパスし、残りの要素を返します。 例えば次が挙げられます。
' Returns a list of customers. The query ignores all
' customers until the first customer for whom
' IsSubscriber returns false. That customer and all
' remaining customers are returned.
Dim customerList = From cust In customers
Skip While IsSubscriber(cust)
Take 句
任意。
Take
句は、コレクションの先頭から指定した数の連続する要素を返します。 例えば次が挙げられます。
' Returns the first 10 customers.
Dim customerList = From cust In customers
Take 10
Take While 句
任意。
Take While
句には、指定した条件がtrue
され、残りの要素がバイパスされている限り、コレクション内の要素が含まれます。 例えば次が挙げられます。
' Returns a list of customers. The query returns
' customers until the first customer for whom
' HasOrders returns false. That customer and all
' remaining customers are ignored.
Dim customersWithOrders = From cust In customers
Order By cust.Orders.Count Descending
Take While HasOrders(cust)
その他の LINQ クエリ機能を使用する
LINQ によって提供される列挙可能な型とクエリ可能な型のメンバーを呼び出すことによって、追加の LINQ クエリ機能を使用できます。 クエリ式の結果に対して特定のクエリ演算子を呼び出すことで、これらの追加機能を使用できます。 たとえば、次の例では、 Enumerable.Union メソッドを使用して、2 つのクエリの結果を 1 つのクエリ結果に結合します。 Enumerable.ToList メソッドを使用して、クエリ結果を汎用リストとして返します。
Public Function GetAllCustomers() As List(Of Customer)
Dim customers1 = From cust In domesticCustomers
Dim customers2 = From cust In internationalCustomers
Dim customerList = customers1.Union(customers2)
Return customerList.ToList()
End Function
その他の LINQ 機能の詳細については、「 標準クエリ演算子の概要」を参照してください。
LINQ to SQL を使用してデータベースに接続する
Visual Basic では、LINQ to SQL ファイルを使用してアクセスする SQL Server データベース オブジェクト (テーブル、ビュー、ストアド プロシージャなど) を特定します。 LINQ to SQL ファイルの拡張子は .dbml です。
SQL Server データベースへの有効な接続がある場合は、 LINQ to SQL Classes 項目テンプレートをプロジェクトに追加できます。 オブジェクト リレーショナル デザイナー (O/R デザイナー) が表示されます。 O/R デザイナーを使用すると、コードでアクセスする項目を サーバー エクスプローラー/Database Explorer からデザイナー画面にドラッグできます。 LINQ to SQL ファイルは、 DataContext オブジェクトをプロジェクトに追加します。 このオブジェクトには、アクセスするテーブルとビューのプロパティとコレクション、および呼び出すストアド プロシージャのメソッドが含まれます。 LINQ to SQL (.dbml) ファイルへの変更を保存したら、O/R デザイナーで定義されている DataContext オブジェクトを参照することで、コード内のこれらのオブジェクトにアクセスできます。 プロジェクトの DataContext オブジェクトは、LINQ to SQL ファイルの名前に基づいて名前が付けられます。 たとえば、Northwind.dbml という名前の LINQ to SQL ファイルでは、NorthwindDataContext
という名前のDataContext オブジェクトが作成されます。
詳細な手順の例については、「 方法: データベースにクエリを実行する 」と「 方法: ストアド プロシージャを呼び出す」を参照してください。
LINQ をサポートする Visual Basic の機能
Visual Basic には、LINQ をシンプルに使用し、LINQ クエリを実行するために記述する必要があるコードの量を減らす他の注目すべき機能が含まれています。 これには以下が含まれます。
匿名型。クエリ結果に基づいて新しい型を作成できます。
暗黙的に型指定された変数。型の指定を延期し、コンパイラがクエリ結果に基づいて型を推論できるようにします。
拡張メソッド。型自体を変更せずに、独自のメソッドを使用して既存の型を拡張できます。
詳細については、「 LINQ をサポートする Visual Basic 機能」を参照してください。
遅延クエリと即時クエリ実行
クエリの実行は、クエリの作成とは別です。 クエリが作成されると、その実行は別のメカニズムによってトリガーされます。 クエリは、定義が定義されるとすぐに実行できます (即時実行)、または定義を格納して、後でクエリを実行できます (遅延実行)。
既定では、クエリを作成しても、クエリ自体はすぐには実行されません。 代わりに、クエリ定義は、クエリ結果を参照するために使用される変数に格納されます。
For…Next
ループなど、後でコード内でクエリ結果変数にアクセスすると、クエリが実行されます。 このプロセスは、 遅延実行と呼ばれます。
クエリは、定義時に実行することもできます。これは 即時実行と呼ばれます。 クエリ結果の個々の要素へのアクセスを必要とするメソッドを適用することで、即時実行をトリガーできます。 これは、 Count
、 Sum
、 Average
、 Min
、 Max
などの集計関数を含めた結果です。 集計関数の詳細については、「 集計句」を参照してください。
ToList
メソッドまたはToArray
メソッドを使用すると、即時実行も強制されます。 これは、クエリをすぐに実行して結果をキャッシュする場合に便利です。 これらのメソッドの詳細については、「 データ型の変換」を参照してください。
クエリの実行の詳細については、「 最初の LINQ クエリの記述」を参照してください。
Visual Basic の XML
Visual Basic の XML 機能には、XML リテラルと XML 軸プロパティが含まれています。このプロパティを使用すると、コード内で XML を簡単に作成、アクセス、クエリ、および変更できます。 XML リテラルを使用すると、コード内で XML を直接記述できます。 Visual Basic コンパイラは、XML をファースト クラスのデータ オブジェクトとして扱います。
次のコード例は、XML 要素を作成し、そのサブ要素と属性にアクセスし、LINQ を使用して要素の内容にクエリを実行する方法を示しています。
' Place Imports statements at the top of your program.
Imports <xmlns:ns="http://SomeNamespace">
Module Sample1
Sub SampleTransform()
' Create test by using a global XML namespace prefix.
Dim contact =
<ns:contact>
<ns:name>Patrick Hines</ns:name>
<ns:phone ns:type="home">206-555-0144</ns:phone>
<ns:phone ns:type="work">425-555-0145</ns:phone>
</ns:contact>
Dim phoneTypes =
<phoneTypes>
<%= From phone In contact.<ns:phone>
Select <type><%= phone.@ns:type %></type>
%>
</phoneTypes>
Console.WriteLine(phoneTypes)
End Sub
End Module
詳細については、 XML を参照してください。
関連リソース
トピック | 説明 |
---|---|
XML | クエリを実行できる Visual Basic の XML 機能について説明します。この機能を使用すると、Visual Basic コードに XML をファースト クラスのデータ オブジェクトとして含めることができます。 |
クエリ | Visual Basic で使用できるクエリ句に関する参照情報を提供します。 |
統合言語クエリ (LINQ) | LINQ の一般的な情報、プログラミング ガイダンス、サンプルが含まれています。 |
午前 9 時から午後 5 時まで | LINQ to SQL の一般的な情報、プログラミング ガイダンス、サンプルが含まれています。 |
LINQ to Objects | LINQ to Objects の一般的な情報、プログラミング ガイダンス、サンプルが含まれています。 |
LINQ to ADO.NET (ポータル ページ) | LINQ to ADO.NET の一般的な情報、プログラミング ガイダンス、サンプルへのリンクが含まれています。 |
LINQ to XML | LINQ to XML の一般的な情報、プログラミング ガイダンス、サンプルが含まれています。 |
方法とチュートリアルに関するトピック
方法: 更新、挿入、および削除を実行するストアド プロシージャを割り当てる (O/R デザイナー)
注目の書籍の章
第 17 章:Visual Basic 2008 のプログラミングにおける LINQ
こちらも参照ください
.NET