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

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

このトピックでは、クエリ式の構文で、GroupJoin メソッドおよび Join メソッドを使用して、AdventureWorks Sales Model を照会する例を取り上げます。これらの例で使用されている、AdventureWorks Sales Model は、AdventureWorks サンプル データベースの Contact、Address、Product、SalesOrderHeader、SalesOrderDetail の各テーブルから作成されています。

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

Option Explicit On
Option Strict On
Imports L2EExamplesVB.AdventureWorksModel
Imports System.Data.Objects
Imports System.Globalization
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using AdventureWorksModel;
using System.Globalization;

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

GroupJoin

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

Using AWEntities As New AdventureWorksEntities
    Dim orders As ObjectQuery(Of SalesOrderHeader) = AWEntities.SalesOrderHeader
    Dim details As ObjectQuery(Of SalesOrderDetail) = AWEntities.SalesOrderDetail

    Dim query = _
        From order In orders _
        Group Join detail In details _
        On order.SalesOrderID _
        Equals detail.SalesOrderID Into orderGroup = Group _
        Select New With _
        { _
            .CustomerID = order.SalesOrderID, _
            .OrderCount = orderGroup.Count() _
        }

    For Each order In query
        Console.WriteLine("CustomerID: {0}  Orders Count: {1}", _
            order.CustomerID, order.OrderCount)
    Next
End Using
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    ObjectQuery<SalesOrderHeader> orders = AWEntities.SalesOrderHeader;
    ObjectQuery<SalesOrderDetail> details = AWEntities.SalesOrderDetail;

    var query =
        from order in orders
        join detail in details
        on order.SalesOrderID
        equals detail.SalesOrderID into orderGroup
        select new
        {
            CustomerID = order.SalesOrderID,
            OrderCount = orderGroup.Count()
        };

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

次の例では、Contact テーブルおよび SalesOrderHeader テーブルに対して GroupJoin を実行して、連絡先ごとの注文数を調べます。各連絡先の注文数と ID が表示されます。

Using AWEntities As New AdventureWorksEntities
    Dim contacts As ObjectQuery(Of Contact) = AWEntities.Contact
    Dim orders As ObjectQuery(Of SalesOrderHeader) = AWEntities.SalesOrderHeader

    Dim query = _
        From contact In contacts _
            Group Join order In orders _
            On contact.ContactID _
            Equals order.Contact.ContactID Into contactGroup = Group _
            Select New With { _
                .ContactID = contact.ContactID, _
                .OrderCount = contactGroup.Count(), _
                .Orders = contactGroup.Select(Function(order) order)}

    For Each group In query
        Console.WriteLine("ContactID: {0}", group.ContactID)
        Console.WriteLine("Order count: {0}", group.OrderCount)

        For Each orderInfo In group.Orders
            Console.WriteLine("   Sale ID: {0}", orderInfo.SalesOrderID)
        Next

        Console.WriteLine("")
    Next
End Using
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    ObjectQuery<Contact> contacts = AWEntities.Contact;
    ObjectQuery<SalesOrderHeader> orders = AWEntities.SalesOrderHeader;

    var query =
        from contact in contacts
        join order in orders
        on contact.ContactID
        equals order.Contact.ContactID into contactGroup
        select new
        {
            ContactID = contact.ContactID,
            OrderCount = contactGroup.Count(),
            Orders = contactGroup.Select(order => order)
        };

    foreach (var group in query)
    {
        Console.WriteLine("ContactID: {0}", group.ContactID);
        Console.WriteLine("Order count: {0}", group.OrderCount);
        foreach (var orderInfo in group.Orders)
        {
            Console.WriteLine("   Sale ID: {0}", orderInfo.SalesOrderID);
        }
        Console.WriteLine("");
    }
}

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

Using AWEntities As New AdventureWorksEntities
    Dim contacts As ObjectQuery(Of Contact) = AWEntities.Contact
    Dim orders As ObjectQuery(Of SalesOrderHeader) = AWEntities.SalesOrderHeader

    Dim query = _
        From contact In contacts _
            Group Join order In orders _
            On contact.ContactID _
            Equals order.Contact.ContactID Into contactGroup = Group _
            Select New With { _
                .ContactID = contact.ContactID, _
                .OrderCount = contactGroup.Count(), _
                .Orders = contactGroup.Select(Function(order) order)}

    For Each group In query
        Console.WriteLine("ContactID: {0}", group.ContactID)
        Console.WriteLine("Order count: {0}", group.OrderCount)

        For Each orderInfo In group.Orders
            Console.WriteLine("   Sale ID: {0}", orderInfo.SalesOrderID)
        Next

        Console.WriteLine("")
    Next
End Using
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    ObjectQuery<Contact> contacts = AWEntities.Contact;
    ObjectQuery<SalesOrderHeader> orders = AWEntities.SalesOrderHeader;

    var query =
        from contact in contacts
        join order in orders
        on contact.ContactID
        equals order.Contact.ContactID into contactGroup
        select new
        {
            ContactID = contact.ContactID,
            OrderCount = contactGroup.Count(),
            Orders = contactGroup.Select(order => order)
        };

    foreach (var group in query)
    {
        Console.WriteLine("ContactID: {0}", group.ContactID);
        Console.WriteLine("Order count: {0}", group.OrderCount);
        foreach (var orderInfo in group.Orders)
        {
            Console.WriteLine("   Sale ID: {0}", orderInfo.SalesOrderID);
        }
        Console.WriteLine("");
    }
}

Join

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

Using AWEntities As New AdventureWorksEntities
    Dim orders As ObjectQuery(Of SalesOrderHeader) = AWEntities.SalesOrderHeader
    Dim details As ObjectQuery(Of SalesOrderDetail) = AWEntities.SalesOrderDetail

    Dim query = _
        From ord In orders _
        Join det In details _
        On ord.SalesOrderID Equals det.SalesOrderID _
        Where ord.OnlineOrderFlag = True _
                And ord.OrderDate.Month = 8 _
        Select New With _
        { _
            .SalesOrderID = ord.SalesOrderID, _
            .SalesOrderDetailID = det.SalesOrderDetailID, _
            .OrderDate = ord.OrderDate, _
            .ProductID = det.ProductID _
        }

    For Each ord In query
        Console.WriteLine("{0}" & vbTab & "{1}" & vbTab & "{2:d}" & vbTab & "{3}", _
            ord.SalesOrderID, _
            ord.SalesOrderDetailID, _
            ord.OrderDate, _
            ord.ProductID)
    Next
End Using
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    ObjectQuery<SalesOrderHeader> orders = AWEntities.SalesOrderHeader;
    ObjectQuery<SalesOrderDetail> details = AWEntities.SalesOrderDetail;

    var query =
        from order in orders
        join detail in details
        on order.SalesOrderID equals detail.SalesOrderID
        where order.OnlineOrderFlag == true
        && order.OrderDate.Month == 8
        select new
        {
            SalesOrderID = order.SalesOrderID,
            SalesOrderDetailID = detail.SalesOrderDetailID,
            OrderDate = order.OrderDate,
            ProductID = detail.ProductID
        };

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

参照

概念

クエリ式の構文例 (LINQ to Entities)