複数テーブルにまたがるクエリ (LINQ to DataSet)
LINQ to DataSet では、1 つのテーブルを対象とするクエリに加え、複数のテーブルを対象とするクエリを実行できます。このようなクエリは、統合を使用して実現されます。 結合とは、あるデータ ソース内のオブジェクトを、他方のデータ ソース内で共通の属性 (たとえば製品や連絡先 ID) を持つオブジェクトと関連付けることです。 オブジェクト指向プログラミングでは、それぞれのオブジェクトが別のオブジェクトを参照するメンバーを持つため、オブジェクト間のリレーションシップを比較的簡単にナビゲートできます。ただし、外部データベース テーブル内でのリレーションシップは、これほど簡単にはナビゲートできません。 データベース テーブルには、組み込みのリレーションシップがありません。このようなケースでは、結合操作を使用して、互いのソースの要素を対応付けることができます。 たとえば、製品情報と売上情報が 2 つのテーブルに格納されている場合、結合操作を使用して、同じ販売注文の売上情報と製品を対応付けることができます。
統合言語クエリ (LINQ) フレームワークには、Join と GroupJoin の 2 つの結合演算子が用意されています。これらの演算子は、キーが等しいときだけ 2 つのデータ ソースを対応付ける結合方法である等結合を実行します (これに対し、Transact-SQL では、equals 以外に less than 演算子などの結合演算子がサポートされます)。
リレーショナル データベース用語では、Join は内部結合を実行します。 内部結合とは、対応するデータセット内で一致するオブジェクトがあるオブジェクトのみが返される結合です。
リレーショナル データベース用語で GroupJoin 演算子に相当するものはありません。この演算子は、内部結合と左外部結合のスーパーセットを実装します。左外部結合とは、関連のある要素が 2 つ目のコレクションに存在しない場合でも 1 つ目 (左側) のコレクションの各要素を返す結合です。
結合の詳細については、「結合演算」を参照してください。
例
次の例では、AdventureWorks サンプル データベースの 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)