Navegando em DataRelations

Uma das principais funções de um DataRelation é permitir a navegação de um DataTable para outro em um DataSet. Isso permite recuperar todos os objetos relacionados de DataRow em um DataTable quando receber um único DataRow de um DataTable relacionado. Por exemplo, após estabelecer um DataRelation entre uma tabela de clientes e outra de pedidos, você pode recuperar todas as linhas de pedidos de uma linha de cliente específica usando GetChildRows.

O exemplo de código a seguir cria um DataRelation entre as tabelas de Clientes e de Pedidos de um DataSet, retornando todos os pedidos de cada cliente.

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

O exemplo a seguir se baseia no exemplo anterior, relacionando quatro tabelas juntas e navegando nessas relações. Como no exemplo anterior, CustomerID relaciona a tabela de Clientes à tabela de Pedidos. Para cada cliente na tabela Clientes, são determinadas todas as linhas filho na tabela Pedidos, para retornar o número de pedidos de um cliente específico e seus valores de OrderID.

O exemplo expandido também retorna os valores das tabelas OrderDetails e de Produtos. A tabela de Pedidos está relacionada à OrderDetails usando OrderID para determinar, em cada pedido de cliente, os produtos e quantidades pedidos. Como a tabela OrderDetails contém somente o ProductID de um produto pedido, OrderDetails está relacionada à tabela de Produtos usando ProductID para retornar o ProductName. Nessa relação, a tabela de Produtos é o pai e a tabela Order Details é o filho. Como resultado, ao iterar por meio da tabela OrderDetails, GetParentRow é chamado para recuperar o valor ProductName relacionado.

Note que, quando o DataRelation é criado para as tabelas de Clientes e dePedidos, nenhum valor é especificado para o sinalizador createConstraints (o padrão é true). Isso pressupõe que todas as linhas na tabela de Pedidos tenham um valor CustomerID existente na tabela de Clientes pai. Se houver um CustomerID na tabela de Pedidos que não exista na tabela de Clientes, um ForeignKeyConstraint gerará uma exceção.

Quando a coluna filho contiver valores que talvez não constem na coluna pai, defina o sinalizador createConstraints como false ao adicionar o DataRelation. No exemplo, o sinalizador createConstraints é definido como false para o DataRelation entre as tabelas de Pedidos e OrderDetails. Isso habilita o aplicativo a retornar todos os registros da tabela OrderDetails e apenas um subconjunto de registros da tabela de Pedidos sem gerar uma exceção de tempo de execução. O exemplo expandido gera saída no formato a seguir.

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  

O código a seguir é um exemplo expandido, no qual são retornados os valores das tabelas OrderDetails e de Produtos, porém com apenas um subconjunto dos registros na tabela de Pedidos.

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

Confira também