次の方法で共有


クエリ式の構文例 : 結合演算子 (LINQ to DataSet)

結合は、リレーショナル データベース テーブルのように互いにナビゲート可能なリレーションシップを持たないデータ ソースをターゲットとするクエリにおいて重要な操作です。 2 つのデータ ソースを結合する操作とは、あるデータ ソース内のオブジェクトを、他方のデータ ソース内で共通の属性を持つオブジェクトと関連付けることです。 詳細については、「標準クエリ演算子の概要」を参照してください。

このトピックでは、GroupJoin メソッドおよび Join メソッドで、クエリ式の構文を使って DataSet に対するクエリを実行する例を紹介しています。

これらの例で使用されている FillDataSet メソッドの指定については、「DataSet へのデータの読み込み」を参照してください。

このトピックの例には、AdventureWorks サンプル データベースの Contact、Address、Product、SalesOrderHeader、SalesOrderDetail の各テーブルが使用されています。

このトピックの例には、次の using/Imports ステートメントが使用されています。

Option Explicit On

Imports System
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Common
Imports System.Globalization
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;

詳細については、「方法 : Visual Studio で LINQ to DataSet プロジェクトを作成する」を参照してください。

GroupJoin

この例では、SalesOrderHeader テーブルおよび SalesOrderDetail テーブルに対して GroupJoin を実行することによって、顧客ごとの注文数を調べます。 GroupJoin は、左外部結合に相当します。つまり、1 つ目 (左側) のデータ ソースに存在するすべての要素は、関連する要素がもう一方のデータ ソースに存在するかどうかに関係なく返されます。

' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)

Dim orders = ds.Tables("SalesOrderHeader").AsEnumerable()
Dim details = ds.Tables("SalesOrderDetail").AsEnumerable()

Dim query = _
        From order In orders _
        Group Join detail In details _
            On order.Field(Of Integer)("SalesOrderID") _
            Equals detail.Field(Of Integer)("SalesOrderID") Into ords = Group _
        Select New With _
            { _
                .CustomerID = order.Field(Of Integer)("SalesOrderID"), _
                .ords = ords.Count() _
            }

For Each order In query
    Console.WriteLine("CustomerID: {0}  Orders Count: {1}", _
        order.CustomerID, order.ords)
Next
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

var orders = ds.Tables["SalesOrderHeader"].AsEnumerable();
var details = ds.Tables["SalesOrderDetail"].AsEnumerable();

var query =
    from order in orders
    join detail in details
    on order.Field<int>("SalesOrderID")
    equals detail.Field<int>("SalesOrderID") into ords
    select new
    {
        CustomerID =
            order.Field<int>("SalesOrderID"),
        ords = ords.Count()
    };

foreach (var order in query)
{
    Console.WriteLine("CustomerID: {0}  Orders Count: {1}",
        order.CustomerID,
        order.ords);
}

この例では、Contact テーブルと SalesOrderHeader テーブルに対して GroupJoin を実行します。 GroupJoin は、左外部結合に相当します。つまり、1 つ目 (左側) のデータ ソースに存在するすべての要素は、関連する要素がもう一方のデータ ソースに存在するかどうかに関係なく返されます。

' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)

Dim contacts As DataTable = ds.Tables("Contact")
Dim orders As DataTable = ds.Tables("SalesOrderHeader")

Dim query = _
    From contact In contacts.AsEnumerable(), order In orders.AsEnumerable() _
    Where (contact.Field(Of Integer)("ContactID") = _
        order.Field(Of Integer)("ContactID")) _
    Select New With _
        { _
            .ContactID = contact.Field(Of Integer)("ContactID"), _
            .SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _
            .FirstName = contact.Field(Of String)("FirstName"), _
            .Lastname = contact.Field(Of String)("Lastname"), _
            .TotalDue = order.Field(Of Decimal)("TotalDue") _
        }

For Each contact_order In query
    Console.Write("ContactID: " & contact_order.ContactID)
    Console.Write(" SalesOrderID: " & contact_order.SalesOrderID)
    Console.Write(" FirstName: " & contact_order.FirstName)
    Console.Write(" Lastname: " & contact_order.Lastname)
    Console.WriteLine(" TotalDue: " & contact_order.TotalDue)
Next
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

DataTable contacts = ds.Tables["Contact"];
DataTable orders = ds.Tables["SalesOrderHeader"];

var query =
    from contact in contacts.AsEnumerable()
    join order in orders.AsEnumerable()
    on contact.Field<Int32>("ContactID") equals
    order.Field<Int32>("ContactID")
    select new
    {
        ContactID = contact.Field<Int32>("ContactID"),
        SalesOrderID = order.Field<Int32>("SalesOrderID"),
        FirstName = contact.Field<string>("FirstName"),
        Lastname = contact.Field<string>("Lastname"),
        TotalDue = order.Field<decimal>("TotalDue")
    };


foreach (var contact_order in query)
{
    Console.WriteLine("ContactID: {0} "
                    + "SalesOrderID: {1} "
                    + "FirstName: {2} "
                    + "Lastname: {3} "
                    + "TotalDue: {4}",
        contact_order.ContactID,
        contact_order.SalesOrderID,
        contact_order.FirstName,
        contact_order.Lastname,
        contact_order.TotalDue);
}

Join

この例では、SalesOrderHeader テーブルと SalesOrderDetail テーブルを結合し、8 月以降のオンラインでの注文を取得します。

' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)

Dim orders As DataTable = ds.Tables("SalesOrderHeader")
Dim details As DataTable = ds.Tables("SalesOrderDetail")


Dim query = _
    From order In orders.AsEnumerable() _
    Join detail In details.AsEnumerable() _
    On order.Field(Of Integer)("SalesOrderID") Equals _
            detail.Field(Of Integer)("SalesOrderID") _
    Where order.Field(Of Boolean)("OnlineOrderFlag") = True And _
            order.Field(Of DateTime)("OrderDate").Month = 8 _
    Select New With _
    { _
        .SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _
        .SalesOrderDetailID = detail.Field(Of Integer)("SalesOrderDetailID"), _
        .OrderDate = order.Field(Of DateTime)("OrderDate"), _
        .ProductID = detail.Field(Of Integer)("ProductID") _
    }

For Each order In query
    Console.WriteLine(order.SalesOrderID & vbTab & _
        order.SalesOrderDetailID & vbTab & _
        order.OrderDate & vbTab & _
        order.ProductID)
Next
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

DataTable orders = ds.Tables["SalesOrderHeader"];
DataTable details = ds.Tables["SalesOrderDetail"];

var query =
    from order in orders.AsEnumerable()
    join detail in details.AsEnumerable()
    on order.Field<int>("SalesOrderID") equals
        detail.Field<int>("SalesOrderID")
    where order.Field<bool>("OnlineOrderFlag") == true
    && order.Field<DateTime>("OrderDate").Month == 8
    select new
    {
        SalesOrderID =
            order.Field<int>("SalesOrderID"),
        SalesOrderDetailID =
            detail.Field<int>("SalesOrderDetailID"),
        OrderDate =
            order.Field<DateTime>("OrderDate"),
        ProductID =
            detail.Field<int>("ProductID")
    };


foreach (var order in query)
{
    Console.WriteLine("{0}\t{1}\t{2:d}\t{3}",
        order.SalesOrderID,
        order.SalesOrderDetailID,
        order.OrderDate,
        order.ProductID);
}

参照

概念

DataSet へのデータの読み込み

標準クエリ演算子の概要

その他の技術情報

LINQ to DataSet の例