次の方法で共有


Visual Basic での LINQ の概要

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 ループなど、後でコード内でクエリ結果変数にアクセスすると、クエリが実行されます。 このプロセスは、 遅延実行と呼ばれます。

クエリは、定義時に実行することもできます。これは 即時実行と呼ばれます。 クエリ結果の個々の要素へのアクセスを必要とするメソッドを適用することで、即時実行をトリガーできます。 これは、 CountSumAverageMinMaxなどの集計関数を含めた結果です。 集計関数の詳細については、「 集計句」を参照してください。

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

こちらも参照ください