Explorar una relación entre tablas

Una de las funciones principales de una DataRelation es la de permitir la exploración de una DataTable en otra dentro de un DataSet. Esto permite recuperar todos los objetos DataRow relacionados de una DataTable cuando se da una única DataRow de una DataTable relacionada. Por ejemplo, después de establecer una DataRelation entre una tabla de clientes y una tabla de pedidos, es posible recuperar todas las filas de pedidos de una fila de clientes determinada mediante DataRow.GetChildRows.

En el siguiente ejemplo de código se crea una DataRelation entre la tabla Customers y la tabla Orders de un DataSet, y se devuelven todos los pedidos de cada cliente.

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"]);
}

El ejemplo siguiente se basa en el anterior; se relacionan cuatro tablas y se exploran dichas relaciones. Como en el ejemplo anterior, CustomerID relaciona la tabla Customers con la tabla Orders. Para cada cliente de la tabla Customers se determinan todas las filas secundarias de la tabla Orders con el fin de devolver el número de pedidos que tiene un cliente concreto y sus valores de OrderID.

El ejemplo ampliado también devuelve los valores de las tablas OrderDetails y Products. La tabla Orders está relacionada con la tabla OrderDetails mediante OrderID con el fin de determinar, para cada pedido de cliente, qué productos y cantidades se pidieron. Como la tabla OrderDetails sólo contiene el ProductID de un producto pedido, OrderDetails está relacionada con Products mediante ProductID para devolver el ProductName. En esta relación, Products es la tabla primaria y Order Details es la secundaria. Por tanto, al establecer una iteración en la tabla OrderDetails se llama a GetParentRow para recuperar el valor de ProductName relacionado.

Hay que tener en cuenta que al crear la DataRelation para las tablas Customers y Orders no se especifica ningún valor para el indicador createConstraints (el valor predeterminado es true). Se supone que todas las filas de la tabla Orders tienen un valor CustomerID que existe en la tabla primaria Customers. Si un CustomerID existe en la tabla Orders pero no existe en la tabla Customers, una ForeignKeyConstraint hará que se inicie una excepción.

En aquellas situaciones en las que la columna secundaria pueda contener valores no incluidos en la columna primaria, hay que asignar el valor false al indicador createConstraints cuando se agregue la DataRelation. En el ejemplo, el indicador createConstraints tiene el valor false para la DataRelation entre las tablas Orders y OrderDetails. Esto permite que la aplicación devuelva todos los registros de la tabla OrderDetails y sólo un subconjunto de registros de la tabla Orders sin generar una excepción en tiempo de ejecución. El ejemplo ampliado genera el resultado con el siguiente formato.

      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

El siguiente ejemplo de código es un ejemplo ampliado en el que se devuelven los valores de las tablas OrderDetails y Products, y sólo se devuelve un subconjunto de los registros de la tabla Orders.

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"]);
    }
  }
}

Vea también

Crear y utilizar DataSets | DataRelation (Clase) | DataRow (Clase) | DataSet (Clase)