次の方法で共有


テーブル間のリレーションシップの移動

DataRelation の主な機能の 1 つは、DataSet 内で 1 つの DataTable から別の DataTable に移動できることです。この移動により、関連付けられた DataTable から単一の DataRow を指定すると、1 つの DataTable 内の関連するすべての DataRow オブジェクトを取得できます。たとえば、顧客のテーブルとオーダーのテーブル間に DataRelation を確立すると、DataRow.GetChildRows を使用して特定の顧客行のオーダー行をすべて取得できます。

DataSetCustomers テーブルと Orders テーブル間の DataRelation を作成し、各顧客のすべてのオーダーを返すコード例を次に示します。

Dim custOrderRel As DataRelation = custDS.Relations.Add("CustOrders", _
                     custDS.Tables("Customers").Columns("CustomerID"), _
                     custDS.Tables("Orders").Columns("CustomerID")) 

Dim custRow As DataRow
Dim orderRow As DataRow

For Each custRow in custDS.Tables("Customers").Rows
  Console.WriteLine(custRow("CustomerID"))
  For Each orderRow in custRow.GetChildRows(custOrderRel)
    Console.WriteLine(orderRow("OrderID"))
  Next
Next
[C#]
DataRelation custOrderRel = custDS.Relations.Add("CustOrders",
                     custDS.Tables["Customers"].Columns["CustomerID"],
                     custDS.Tables["Orders"].Columns["CustomerID"]);
foreach (DataRow custRow in custDS.Tables["Customers"].Rows)
{
  Console.WriteLine(custRow["CustomerID"]);
  foreach (DataRow orderRow in custRow.GetChildRows(custOrderRel))
    Console.WriteLine(orderRow["OrderID"]);
}

上記のコード例に基づいて、4 つのテーブルを相互に関連付け、そのテーブルのリレーションシップ間を移動するコード例を次に示します。上記の例に示すように、CustomerIDCustomers テーブルを Orders テーブルに関連付けます。Customers テーブルにある各顧客に対しては、Orders テーブルにあるすべての子の行が確定され、該当する顧客のオーダー数とその OrderID の値が返されます。

展開された例では、OrderDetails テーブルおよび Products テーブルからも値が返されます。各顧客のオーダーに対しては、オーダーされた製品および数量を示すために、OrderID を使用して Orders テーブルが OrderDetails テーブルに関連付けられます。OrderDetails テーブルに含まれているのは、オーダーされた製品の ProductID だけであるため、ProductID を使用して、OrderDetailsProducts に関連付けて ProductName を返します。このリレーションシップでは、Products テーブルが親となり、Order Details テーブルが子となります。その結果、OrderDetails テーブルを順次処理すると、GetParentRow が呼び出され、関連付けられた ProductName の値を取得します。

DataRelationCustomers テーブルと Orders テーブルに対して作成された場合には、createConstraints フラグには値が指定されません (既定値は true)。これは、Orders テーブルにあるすべての行に対して親の Customers テーブルにある CustomerID の値が設定されているためです。Orders テーブルに CustomerID が存在し、Customers テーブルに CustomerID が存在しない場合には、ForeignKeyConstraint は例外をスローします。

親の列に含まれていない値が子の列に含まれる場合、DataRelation の追加時に createConstraints フラグが false に設定されます。例では、Orders テーブルと OrderDetails テーブル間の DataRelation に対して、createConstraints フラグが false に設定されています。このため、このアプリケーションでは OrderDetails テーブルからすべてのレコードを返し、実行時に例外を生成せずに Orders テーブルからレコードのサブセットだけを返すことができます。展開された例では、次の形式で出力が生成されます。

      Customer ID: NORTS
        Order ID: 10517
              Order Date: 4/24/1997 12:00:00 AM
                 Product: Filo Mix
                Quantity: 6   
                 Product: Raclette Courdavault
                Quantity: 4
                 Product: Outback Lager
                Quantity: 6
        Order ID: 11057
              Order Date: 4/29/1998 12:00:00 AM
                 Product: Outback Lager
                Quantity: 3

Orders テーブルのレコードのサブセットだけと共に、OrderDetails テーブルと Products テーブルからの値が返された場合に展開された例を次のコード例に示します。

Dim custOrderRel As DataRelation = custDS.Relations.Add("CustOrders", _
                     custDS.Tables("Customers").Columns("CustomerID"), _
                     custDS.Tables("Orders").Columns("CustomerID"))

Dim orderDetailRel As DataRelation = custDS.Relations.Add("OrderDetail", _
                     custDS.Tables("Orders").Columns("OrderID"), _
                     custDS.Tables("OrderDetails").Columns("OrderID"), false)

Dim orderProductRel As DataRelation = custDS.Relations.Add("OrderProducts", _
                     custDS.Tables("Products").Columns("ProductID"), _
                     custDS.Tables("OrderDetails").Columns("ProductID"))

Dim custRow, orderRow, detailRow As DataRow

For Each custRow In custDS.Tables("Customers").Rows
  Console.WriteLine("Customer ID:" & custRow("CustomerID").ToString())

  For Each orderRow In custRow.GetChildRows(custOrderRel)
    Console.WriteLine("  Order ID: " & orderRow("OrderID").ToString())
    Console.WriteLine(vbTab & "Order Date: " & orderRow("OrderDate").ToString())

    For Each detailRow In orderRow.GetChildRows(orderDetailRel)
        Console.WriteLine(vbTab & "   Product: " & detailRow.GetParentRow(orderProductRel)("ProductName").ToString())
        Console.WriteLine(vbTab & "  Quantity: " & detailRow("Quantity").ToString())
    Next
  Next
Next
[C#]
DataRelation custOrderRel = custDS.Relations.Add("CustOrders",
                     custDS.Tables["Customers"].Columns["CustomerID"],
                     custDS.Tables["Orders"].Columns["CustomerID"]);

DataRelation orderDetailRel = custDS.Relations.Add("OrderDetail",
                     custDS.Tables["Orders"].Columns["OrderID"],
                     custDS.Tables["OrderDetails"].Columns["OrderID"], false);

DataRelation orderProductRel = custDS.Relations.Add("OrderProducts",
                     custDS.Tables["Products"].Columns["ProductID"],
                     custDS.Tables["OrderDetails"].Columns["ProductID"]);

foreach (DataRow custRow in custDS.Tables["Customers"].Rows)
{
  Console.WriteLine("Customer ID: " + custRow["CustomerID"]);

  foreach (DataRow orderRow in custRow.GetChildRows(custOrderRel))
  {
    Console.WriteLine("  Order ID: " + orderRow["OrderID"]);
    Console.WriteLine("\tOrder Date: " + orderRow["OrderDate"]);

    foreach (DataRow detailRow in orderRow.GetChildRows(orderDetailRel))
    {
        Console.WriteLine("\t   Product: " + detailRow.GetParentRow(orderProductRel)["ProductName"]);
        Console.WriteLine("\t  Quantity: " + detailRow["Quantity"]);
    }
  }
}

参照

DataSet の作成および使用 | DataRelation クラス | DataRow クラス | DataSet クラス