クエリ式の構文例:結合演算子
結合は、リレーショナル データベース テーブルのように互いにナビゲート可能なリレーションシップを持たないデータ ソースをターゲットとするクエリにおいて重要な操作です。 2 つのデータ ソースを結合する操作とは、あるデータ ソース内のオブジェクトを、他方のデータ ソース内で共通の属性を持つオブジェクトと関連付けることです。 詳細については、「標準クエリ演算子の概要」を参照してください。
このトピックでは、クエリ式構文で、GroupJoin メソッドおよび Join メソッドを使用して、AdventureWorks Sales Model を照会する例を取り上げます。 これらの例で使用されている、AdventureWorks Sales Model は、AdventureWorks サンプル データベースの Contact、Address、Product、SalesOrderHeader、SalesOrderDetail の各テーブルから作成されています。
このトピックの例には、次の using
/Imports
ステートメントが使用されています。
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;
Option Explicit On
Option Strict On
Imports System.Data.Objects
Imports System.Globalization
GroupJoin
例
次の例では、SalesOrderHeader テーブルおよび SalesOrderDetail テーブルに対して GroupJoin を実行することによって、顧客ごとの注文数を調べます。 GroupJoin は、左外部結合に相当します。つまり、1 つ目 (左側) のデータ ソースに存在するすべての要素は、関連する要素がもう一方のデータ ソースに存在するかどうかに関係なく返されます。
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;
ObjectSet<SalesOrderDetail> details = context.SalesOrderDetails;
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);
}
}
Using context As New AdventureWorksEntities
Dim orders As ObjectSet(Of SalesOrderHeader) = context.SalesOrderHeaders
Dim details As ObjectSet(Of SalesOrderDetail) = context.SalesOrderDetails
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
例
次の例では、Contact テーブルおよび SalesOrderHeader テーブルに対して GroupJoin を実行して、連絡先ごとの注文数を調べます。 各連絡先の注文数と ID が表示されます。
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
ObjectSet<Contact> contacts = context.Contacts;
ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;
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
};
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("");
}
}
Using context As New AdventureWorksEntities
Dim contacts As ObjectSet(Of Contact) = context.Contacts
Dim orders As ObjectSet(Of SalesOrderHeader) = context.SalesOrderHeaders
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
Join
例
次の例では、SalesOrderHeader テーブルと SalesOrderDetail テーブルを結合し、8 月以降のオンラインでの注文を取得します。
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;
ObjectSet<SalesOrderDetail> details = context.SalesOrderDetails;
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);
}
}
Using context As New AdventureWorksEntities
Dim orders As ObjectSet(Of SalesOrderHeader) = context.SalesOrderHeaders
Dim details As ObjectSet(Of SalesOrderDetail) = context.SalesOrderDetails
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