DataRelation の移動

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

次のコード例では、DataSetCustomers テーブルと Orders テーブルの間に DataRelation を作成し、各顧客に対するすべての注文を返します。

DataRelation customerOrdersRelation =
    customerOrders.Relations.Add("CustOrders",
    customerOrders.Tables["Customers"].Columns["CustomerID"],
    customerOrders.Tables["Orders"].Columns["CustomerID"]);

foreach (DataRow custRow in customerOrders.Tables["Customers"].Rows)
{
    Console.WriteLine(custRow["CustomerID"].ToString());

    foreach (DataRow orderRow in custRow.GetChildRows(customerOrdersRelation))
    {
        Console.WriteLine(orderRow["OrderID"].ToString());
    }
}
Dim customerOrdersRelation As DataRelation = _
   customerOrders.Relations.Add("CustOrders", _
   customerOrders.Tables("Customers").Columns("CustomerID"), _
   customerOrders.Tables("Orders").Columns("CustomerID"))

Dim custRow, orderRow As DataRow

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

    For Each orderRow In custRow.GetChildRows(customerOrdersRelation)
        Console.WriteLine(orderRow("OrderID").ToString())
    Next
Next

上記の例に基づいて、4 つのテーブルを相互に関連付け、そのテーブルのリレーションシップ間を移動する例を次に示します。 上の例のように、CustomerID によって Customers テーブルが Orders テーブルに関連付けられます。 特定の顧客の注文数とその OrderID の値を返すため、Customers テーブルの顧客ごとに、Orders テーブル内のすべての子の行が特定されます。

展開された例では、OrderDetails テーブルと Products テーブルからも値が返されます。 OrderID を使用して Orders テーブルが OrderDetails テーブルに関連付けられ、顧客の注文ごとに、注文された製品と数量が特定されます。 OrderDetails テーブルに含まれるのは、注文された製品の ProductID だけなので、ProductName を返すため、ProductID を使用して、OrderDetailsProducts に関連付けられます。 この関係では、Products テーブルが親となり、Order Details テーブルが子となります。 その結果、OrderDetails テーブルの反復処理では、GetParentRow を呼び出して、関連付けられた ProductName の値を取得します。

DataRelationCustomers テーブルと Orders テーブルに対して作成されるとき、createConstraints フラグに対して値が指定されていないことに注意してください (既定値は true)。 これにより、Orders テーブルのすべての行に対して、親の Customers テーブルに CustomerID の値が存在するものと設定されます。 Customers テーブルに存在しない CustomerIDOrders テーブルに存在した場合、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  

次のコード例はサンプルを拡張したものであり、OrderDetails テーブルと Products テーブルから値が返され、Orders テーブルからはレコードのサブセットだけが返されます。

DataRelation customerOrdersRelation =
    customerOrders.Relations.Add("CustOrders",
    customerOrders.Tables["Customers"].Columns["CustomerID"],
    customerOrders.Tables["Orders"].Columns["CustomerID"]);

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

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

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

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

        foreach (DataRow detailRow in orderRow.GetChildRows(orderDetailRelation))
        {
            Console.WriteLine("\t Product: " +
                detailRow.GetParentRow(orderProductRelation)["ProductName"]);
            Console.WriteLine("\t Quantity: " + detailRow["Quantity"]);
        }
    }
}
Dim customerOrdersRelation As DataRelation = _
   customerOrders.Relations.Add("CustOrders", _
   customerOrders.Tables("Customers").Columns("CustomerID"), _
   customerOrders.Tables("Orders").Columns("CustomerID"))

Dim orderDetailRelation As DataRelation = _
   customerOrders.Relations.Add("OrderDetail", _
   customerOrders.Tables("Orders").Columns("OrderID"), _
   customerOrders.Tables("OrderDetails").Columns("OrderID"), False)

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

Dim custRow, orderRow, detailRow As DataRow

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

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

        For Each detailRow In orderRow.GetChildRows(orderDetailRelation)
            Console.WriteLine(vbTab & "   Product: " & _
              detailRow.GetParentRow(orderProductRelation) _
              ("ProductName").ToString())
            Console.WriteLine(vbTab & "  Quantity: " & _
              detailRow("Quantity").ToString())
        Next
    Next
Next

関連項目