Visual Basic における LINQ の概要

更新 : 2007 年 11 月

統合言語クエリ (LINQ: Language-Integrated Query) は、Visual Basic にクエリ機能を追加します。この単純かつ強力な機能を使用して、あらゆる種類のデータを操作できます。処理の対象であるデータベースにクエリを送信したり、検索するデータの種類ごとに異なるクエリ構文を使用したりする代わりに、LINQ では、Visual Basic 言語の一部としてのクエリを採用しています。LINQ では、データの型に関係なく、統一された構文を使用します。

LINQ を使用すると、SQL Server データベース、XML、インメモリ配列、インメモリ コレクション、ADO.NET データセットなど、LINQ をサポートするリモートまたはローカルのデータ ソースのデータを照会できます。これは、共通 Visual Basic 言語要素を使用して実行できます。クエリは Visual Basic 言語で記述されるので、クエリ結果は、厳密に型指定されたオブジェクトとして返されます。これらのオブジェクトは IntelliSense をサポートするので、コードの記述時間を短縮でき、さらに、クエリに含まれるエラーを実行時ではなくコンパイル時に把握できます。LINQ クエリは、結果を絞り込むための追加クエリのソースとして使用できます。クエリ結果をユーザーが簡単に表示および変更できるように、コントロールにバインドすることもできます。

たとえば、次のコード例は、コレクションから顧客リストを返し、住所に基づいて顧客をグループ化する LINQ クエリを示しています。

Dim customers As List(Of Customer) = GetCustomerList()

Dim customersByCountry = From cust In customers _
                         Order By cust.Country, cust.City _
                         Group By CountryName = cust.Country _
                         Into RegionalCustomers = Group, Count() _
                         Order By CountryName

For Each country In customersByCountry
  Console.WriteLine(country.CountryName & _
                    " (" & country.Count & ")" & vbCrLf)

  For Each customer In country.RegionalCustomers
    Console.WriteLine(vbTab & customer.CompanyName & _
                      " (" & customer.City & ")")
  Next
Next

このトピックには、次の項目に関する情報が含まれています。

  • LINQ プロバイダ

  • LINQ クエリの構造

  • Visual Basic LINQ クエリ演算子

  • LINQ to SQL を使用したデータベースへの接続

  • LINQ をサポートする Visual Basic の機能

  • クエリの遅延実行と即時実行

  • Visual Basic における XML

  • 関連リソース

  • 方法とチュートリアルのトピック

LINQ プロバイダ

LINQ プロバイダは、Visual Basic LINQ クエリを、クエリ対象のデータ ソースに対応付けます。LINQ クエリを記述すると、そのクエリは、プロバイダによって、データ ソースが実行できるコマンドに変換されます。プロバイダは、ソースのデータを、クエリ結果を構成するオブジェクトに変換する操作も行います。最後に、プロバイダは、データ ソースに更新が送信されるときに、オブジェクトをデータに変換します。

Visual Basic には、次の LINQ プロバイダが含まれています。

  • LINQ to Objects
    LINQ to Objects プロバイダは、インメモリ コレクションとインメモリ配列のクエリを可能にします。オブジェクトが IEnumerable インターフェイスまたは IEnumerable<T> インターフェイスをサポートしている場合、LINQ to Objects プロバイダを使用してクエリを実行できます。

    LINQ to Objects プロバイダは、System.Linq 名前空間をインポートすることで有効にできます。この名前空間は、すべての Visual Basic プロジェクトに対して既定でインポートされます。

    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」を参照してください。オブジェクト リレーショナル デザイナの詳細については、「オブジェクト リレーショナル デザイナ (O/R デザイナ)」を参照してください。

  • LINQ to XML
    LINQ to XML プロバイダは、XML のクエリと変更を可能にします。インメモリ XML を変更することや、XML をファイルから読み込んだりファイルに保存したりすることができます。

    さらに、LINQ to XML プロバイダでは、XML リテラルと XML 軸プロパティを使用して、XML を Visual Basic コード内に直接記述できます。詳細については、「XML (Visual Basic)」を参照してください。

  • LINQ to DataSet
    LINQ to DataSet プロバイダは、ADO.NET データセット内のデータのクエリと更新を可能にします。データセットを使用するアプリケーションに LINQ を追加することで、データセット内のデータのクエリ、集計、および更新などの機能を単純化すると同時に拡張できます。

    詳細については、「LINQ to DataSet」を参照してください。

LINQ クエリの構造

LINQ クエリ (クエリ式とも呼ばれます) は、データ ソースを識別するクエリ句と、クエリの反復変数の組み合わせで構成されます。クエリ式には、並べ替え、フィルタ処理、グループ化、および結合を実行する命令や、ソース データに適用する演算も指定できます。クエリ式の構文は SQL の構文に似ているので、ほとんどの構文は、改めて覚える必要はありません。

クエリ式は、From 句で始まります。この句は、クエリのソース データと、ソース データの各要素を個別に参照するために使用される変数を識別します。これらの変数は、範囲変数または反復変数と呼ばれます。From 句は、Aggregate クエリ以外のクエリでは必須です。このクエリでは、From 句は省略できます。From 句または Aggregate 句でクエリのスコープとソースを識別した後、クエリを絞り込むためのクエリ句を自由に組み合わせて記述できます。クエリ句の詳細については、このトピックの「Visual Basic LINQ クエリ演算子」を参照してください。たとえば、次のクエリでは、顧客データのソース コレクションを customers 変数として識別し、cust という名前の反復変数を識別します。

Dim queryResults = From cust In customers _
                   Select cust.CompanyName

この例はそのままでも有効なクエリですが、結果を絞り込むクエリ句を追加すると、はるかに強力なクエリになります。たとえば、Where 句を追加して、結果を 1 つ以上の値でフィルタ処理できます。クエリ式は、1 行のコードです。追加のクエリ句は、クエリの末尾に単純に追加できます。クエリを読みやすくするために、行連結文字のアンダースコア (_) を使用して、複数のテキスト行に分割できます。次のコード例は、Where 句を含むクエリの例を示しています。

Dim queryResults = From cust In customers _
                   Where cust.Country = "USA"

別の強力なクエリ句として、Select 句があります。この句を使用すると、データ ソースから選択したフィールドだけを返すことができます。LINQ クエリは、厳密に型指定されたオブジェクトの列挙可能なコレクションを返します。クエリは、匿名型または名前付きの型のコレクションを返すことができます。Select 句を使用して、データ ソースから単一のフィールドを返すことができます。これを行った場合、返されるコレクションの型は、その単一のフィールドの型になります。Select 句を使用して、データ ソースから複数のフィールドを返すこともできます。これを行った場合、返されるコレクションの型は、新しい匿名型になります。クエリで返されたフィールドを、指定した名前付きの型のフィールドと一致させることもできます。次のコード例は、データ ソースから選択されたフィールドのデータが設定されたメンバのコレクションで、匿名型のコレクションを返すクエリ式を示します。

Dim queryResults = From cust In customers _
               Where cust.Country = "USA" _
               Select cust.CompanyName, cust.Country

LINQ クエリを使用して、複数のデータ ソースを結合し、単一の結果を返すこともできます。これは、1 つまたは複数の From 句を使用するか、Join クエリ句または Group Join クエリ句を使用して実行できます。次のコード例は、顧客データと注文データを結合し、顧客データと注文データが格納された匿名型のコレクションを返すクエリ式を示します。

Dim queryResults = From cust In customers, ord In orders _
                   Where cust.CustomerID = ord.CustomerID _
                   Select cust, ord

Group Join 句を使用して、顧客オブジェクトのコレクションを格納する階層的なクエリ結果を作成できます。各顧客オブジェクトには、その顧客のすべての注文のコレクションを含むプロパティがあります。次のコード例は、顧客データと注文データを階層的な結果として結合し、匿名型のコレクションを返すクエリ式を示します。このクエリは、顧客の注文データのコレクションを格納する CustomerOrders プロパティを含む型を返します。その顧客のすべての注文の合計を格納する OrderTotal プロパティも含まれます (このクエリは、LEFT OUTER JOIN と同等です)。

Dim queryResults = From cust In customers _
                   Group Join ord In orders On _
                     cust.CustomerID Equals ord.CustomerID _
                     Into CustomerOrders = Group, _
                          OrderTotal = Sum(ord.Total) _
                   Select cust.CompanyName, cust.CustomerID, _
                          CustomerOrders, OrderTotal

上記以外にも、強力なクエリ式を作成するために使用できる、さまざまな LINQ クエリ演算子があります。このトピックの次のセクションで、クエリ式で使用できるさまざまなクエリ句について説明します。Visual Basic クエリ句の詳細については、「クエリ (Visual Basic)」を参照してください。

Visual Basic LINQ クエリ演算子

LINQ クエリをサポートする System.Linq 名前空間とその他の名前空間のクラスには、アプリケーションのニーズに基づいてクエリの作成と絞り込みを行うために呼び出すことができるメソッドが含まれています。Visual Basic には、最も一般的なクエリ句のキーワードがあります。これらについて、次の表で説明します。

  • From 句 (Visual Basic)
    クエリを開始するには、From 句または Aggregate 句のいずれかが必要です。From 句は、クエリのソース コレクションと反復変数を指定します。次に例を示します。

    ' Returns the company name for all customers for whom
    ' State is equal to "WA".
    Dim names = From cust In customers _
                Where cust.State = "WA" _
                Select cust.CompanyName
    
  • Select 句 (Visual Basic)
    省略可能です。クエリの反復変数のセットを宣言します。次に例を示します。

    ' 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 句 (Visual Basic)
    省略可能です。クエリのフィルタ処理条件を指定します。次に例を示します。

    ' 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 句 (Visual Basic)
    省略可能です。クエリ内に列の並べ替え順序を指定します。次に例を示します。

    ' Returns a list of books sorted by price in 
    ' ascending order.
    Dim titlesAscendingPrice = From b In books _
                               Order By b.price
    
  • Join 句 (Visual Basic)
    省略可能です。2 つのコレクションを単一のコレクションに結合します。次に例を示します。

    ' 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 句 (Visual Basic)
    省略可能です。クエリ結果の要素をグループ化します。これを使用して、グループごとに集計関数を適用できます。次に例を示します。

    ' 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 句 (Visual Basic)
    省略可能です。2 つのコレクションを、単一の階層コレクションに結合します。次に例を示します。

    ' 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.Total) _
                       Select cust.CompanyName, cust.CustomerID, _
                              CustomerOrders, TotalOfOrders
    
  • Aggregate 句 (Visual Basic)
    クエリを開始するには、From 句または Aggregate 句のいずれかが必要です。Aggregate 句は、1 つ以上の集計関数をコレクションに適用します。たとえば、Aggregate 句を使用して、クエリで返されたすべての要素の合計を計算できます。

    ' Returns the sum of all order totals.
    Dim orderTotal = Aggregate order In orders _
                     Into Sum(order.Total)
    

    Aggregate 句を使用してクエリを変更することもできます。たとえば、Aggregate 句を使用して、関連するクエリ コレクションに対して計算を実行できます。

    ' Returns the customer company name and largest 
    ' order total for each customer.
    Dim customerMax = From cust In customers _
                      Aggregate order In cust.Orders _
                      Into MaxOrder = Max(order.Total) _
                      Select cust.CompanyName, MaxOrder
    
  • Let 句 (Visual Basic)
    省略可能です。値を計算し、その値をクエリ内の新しい変数に代入します。次に例を示します。

    ' 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 句 (Visual Basic)
    省略可能です。現在の反復変数の値を制限して、クエリ結果内で重複する値を除去します。次に例を示します。

    ' Returns a list of cities with no duplicate entries.
    Dim cities = From item In customers _
                 Select item.City _
                 Distinct
    
  • Skip 句 (Visual Basic)
    省略可能です。コレクション内の指定された数の要素をバイパスし、残りの要素を返します。次に例を示します。

    ' 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 句 (Visual Basic)
    省略可能です。指定された条件が 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 句 (Visual Basic)
    省略可能です。コレクションの先頭から、指定された数の連続する要素を返します。次に例を示します。

    ' Returns the first 10 customers.
    Dim customerList = From cust In customers _
                       Take 10
    
  • Take While 句 (Visual Basic)
    省略可能です。指定された条件が 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)
    

Visual Basic クエリ句の詳細については、「クエリ (Visual Basic)」を参照してください。

LINQ によって提供される列挙可能でクエリ可能な型のメンバを呼び出すことで、追加の LINQ クエリ機能を使用できます。これらの追加機能は、クエリ式の結果に対して特定のクエリ演算子を呼び出すことで使用できます。たとえば、次のコード例では、Union メソッドを使用して、2 つのクエリの結果を、1 つのクエリ結果に結合します。また、ToList<TSource> メソッドを使用して、クエリ結果をジェネリック リストとして返します。

VbVbalrIntroToLINQ#22

追加の LINQ 機能の詳細については、「標準クエリ演算子の概要」を参照してください。

LINQ to SQL を使用したデータベースへの接続

Visual Basic では、アクセスする SQL Server データベース オブジェクト (テーブル、ビュー、ストアド プロシージャなど) を、LINQ to SQL ファイルを使用して識別します。LINQ to SQL ファイルには、.dbml という拡張子が付きます。

SQL Server データベースへの有効な接続が存在する場合は、LINQ to SQL クラス項目テンプレートをプロジェクトに追加できます。これを行うと、オブジェクト リレーショナル デザイナ (O/R デザイナ) が表示されます。O/R デザイナを使用して、コード内でアクセスする項目を、サーバー エクスプローラ/データベース エクスプローラからデザイナ画面にドラッグできます。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)」と「方法 : LINQ を使用してストアド プロシージャを呼び出す (Visual Basic)」を参照してください。

LINQ をサポートする Visual Basic の機能

Visual Basic には、LINQ の使用を単純化し、LINQ クエリを実行するために記述する必要があるコードの量を減らすことができる、注目に値する機能が他にもあります。次のコントロールがあります。

  • 匿名型。クエリ結果に基づいて、新しい型を作成できます。

  • 暗黙的に型指定される変数。型の指定を遅らせ、クエリ結果に基づいてコンパイラで型を推論できます。

  • 拡張メソッド。型自体を変更することなく、独自のメソッドを使用して既存の型を拡張できます。

詳細については、「LINQ をサポートする Visual Basic の機能」を参照してください。

クエリの遅延実行と即時実行

クエリの実行とクエリの作成は分離しています。クエリを作成した後、その実行は、別のメカニズムによってトリガされます。クエリは、定義後すぐに実行 (即時実行) することも、定義を保存しておき、後でクエリを実行 (遅延実行) することもできます。

既定では、クエリを作成しても、クエリ自体が直ちに実行されることはありません。代わりに、クエリ結果を参照するために使用される変数にクエリ定義が格納されます。そのクエリ結果変数が、後でコード内の For?cNext ループなどでアクセスされると、クエリが実行されます。この処理を遅延実行と呼びます。

クエリは、それを定義したときに実行することもできます。これを即時実行と呼びます。即時実行は、クエリ結果の個々の要素にアクセスする必要があるメソッドを適用することで開始できます。Count、Sum、Average、Min、Max などの集計関数を含めることで、この結果を得ることができます。集計関数の詳細については、「Aggregate 句 (Visual Basic)」を参照してください。

ToList メソッドまたは ToArray メソッドを使用することでも、即時実行を開始できます。これは、クエリを直ちに実行し、結果をキャッシュする場合に役に立ちます。これらのメソッドの詳細については、「データ型の変換」を参照してください。

クエリ実行の詳細については、「初めての LINQ クエリの作成 (Visual Basic)」を参照してください。

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 (Visual Basic)」を参照してください。

関連リソース

  • XML (Visual Basic)
    Visual Basic における XML の機能について説明します。これらの機能を使用して照会を行い、XML を最初のクラスのデータ オブジェクトとして Visual Basic コード内に記述できます。

  • クエリ (Visual Basic)
    Visual Basic で使用できるクエリ句のリファレンス情報を示します。

  • 統合言語クエリ (LINQ: Language-Integrated Query)
    LINQ の概要、プログラミング ガイド、およびサンプルを示します。

  • LINQ to SQL
    LINQ to SQL の概要、プログラミング ガイド、およびサンプルを示します。

  • LINQ to Objects
    LINQ to Objects の概要、プログラミング ガイド、およびサンプルを示します。

  • LINQ to ADO.NET (ポータル ページ)
    LINQ to ADO.NET の概要、プログラミング ガイド、およびサンプルへのリンクを示します。

  • LINQ to XML
    LINQ to XML の概要、プログラミング ガイド、およびサンプルを示します.

方法とチュートリアルのトピック

方法 : LINQ を使用してデータベースを照会する (Visual Basic)

方法 : LINQ を使用してストアド プロシージャを呼び出す (Visual Basic)

方法 : LINQ を使用してデータベースのデータを変更する (Visual Basic)

方法 : LINQ の結合を使用してデータを結合する (Visual Basic)

方法 : LINQ を使用してコレクションを並べ替える (Visual Basic)

方法 : LINQ を使用してクエリ結果をフィルタ処理する (Visual Basic)

方法 : LINQ を使用したデータの数、合計、または平均の算出 (Visual Basic)

方法 : LINQ を使用したクエリ結果内の最小値と最大値の検索 (Visual Basic)

チュートリアル : LINQ to SQL クラスの作成 (O/R デザイナ)

方法 : 更新、挿入、および削除を実行するストアド プロシージャを割り当てる (O/R デザイナ)

参照

概念

Visual Basic における LINQ to XML の概要

LINQ to DataSet の概要

DataContext メソッド (O/R デザイナ)

その他の技術情報

統合言語クエリ (LINQ: Language-Integrated Query)

LINQ to SQL

LINQ サンプル

オブジェクト リレーショナル デザイナ (O/R デザイナ)