The Artima Developer Community
Sponsored Link

.NET Buzz Forum
Getting GrandParent columns with ADO.NET

0 replies.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a flat view of this topic  Flat View
Previous Topic   Next Topic
Threaded View: This topic has 0 replies on 1 page
John Papa

Posts: 66
Nickname: papajohn
Registered: Apr, 2005

John Papa is .NET lead developer/architect/author
Getting GrandParent columns with ADO.NET Posted: Apr 23, 2005 1:17 PM
Reply to this message Reply

This post originated from an RSS feed registered with .NET Buzz by John Papa.
Original Post: Getting GrandParent columns with ADO.NET
Feed Title: John Papa
Feed URL: /error.htm?aspxerrorpath=/blogs/john.papa/rss.aspx
Feed Description: .NET Code Samples, Data Access, Patterns and Other Musings
Latest .NET Buzz Posts
Latest .NET Buzz Posts by John Papa
Latest Posts From John Papa

I've recently had a flurry of email asking how to navigate up to a grandparent table using ADO.NET. Assuming that it is not preferable to export all of the data to Xml and use an XPath, ADO.NET offers a few other ADO.NET based solutions. One solution is to use expression based columns. (If you want more of an explanation of how to use expression based columns in ADO.NET, see my Data Points article here in MSDN Magazine.)  

To explain both solutions, I created a DataSet that contains 3 DataTables. The DataTable objects represent Customers, Orders and Order Details from the SQL Server Northwind database. I also create a DataRelation between the Customers and its child table, Orders. Then I create another DataRelation between the Orders and its child table, Order Details. At the end of this code sample, shown below, I have a DataSet with Customers, their Orders and their Order Details linked through relations.

Filling the DataSet with Customers, Orders and Order Details
string sCn = "server=(local);database=northwind;integrated security=true;";
DataSet ds = new DataSet();

using (SqlConnection cn = new SqlConnection(sCn))
{
  cn.Open();
  // Get the Customers
  string sqlCustomers = "SELECT CustomerID, CompanyName, Country "
    + " FROM Customers ORDER BY CustomerID";
  using (SqlCommand cmd = new SqlCommand(sqlCustomers, cn))
    using (SqlDataAdapter da = new SqlDataAdapter(cmd))
      da.Fill(ds, "Customers");
  ds.Tables["Customers"].PrimaryKey = 
    new DataColumn[]{ds.Tables["Customers"].Columns["CustomerID"]};

  // Get the Orders
  string sqlOrders = "SELECT OrderID, CustomerID, OrderDate FROM Orders";
  using (SqlCommand cmd = new SqlCommand(sqlOrders, cn))
    using (SqlDataAdapter da = new SqlDataAdapter(cmd))
      da.Fill(ds, "Orders");
  ds.Tables["Orders"].PrimaryKey = 
    new DataColumn[]{ds.Tables["Orders"].Columns["OrderID"]};
  ds.Relations.Add("C2O", 
    ds.Tables["Customers"].Columns["CustomerID"], 
    ds.Tables["Orders"].Columns["CustomerID"]);

  // Get the Order Details
  StringBuilder sb = new StringBuilder("");
  sb.Append("SELECT od.OrderID, p.ProductID, p.ProductName, ");
  sb.Append(" od.UnitPrice, od.Quantity");
  sb.Append(" FROM [Order Details] od ");
  sb.Append(" INNER JOIN Products p ON od.ProductID = p.ProductID");
  string sqlOrderDetails = sb.ToString();
  using (SqlCommand cmd = new SqlCommand(sqlOrderDetails, cn))
    using (SqlDataAdapter da = new SqlDataAdapter(cmd))
      da.Fill(ds, "Order Details");
  ds.Tables["Order Details"].PrimaryKey = 
    new DataColumn[]{ds.Tables["Order Details"].Columns["OrderID"], 
    ds.Tables["Order Details"].Columns["ProductID"]};
  ds.Relations.Add("O2OD", 
    ds.Tables["Orders"].Columns["OrderID"], 
    ds.Tables["Order Details"].Columns["OrderID"]);
  cn.Close();
}


The first solution I mentioned adds an expression column to the Orders and to the Order Details DataTable objects. The expression column in the Orders DataTable navigates up to its parent DataTable (Customers) via a DataRelation and simply gets the value of the Country column. The expression column in the Order Details DataTable navigates up to its parent DataTable (Orders) via a DataRelation and evaluates the expression column in the Orders DataTable to determine if the country is the US or not.

Grandparent via Expressions
// add an expression column, to help out
ds.Tables["Orders"].Columns.Add("CustomerCountry", typeof(string), "Parent.Country");
ds.Tables["Order Details"].Columns.Add("CountryType", typeof(string), 
  "Iif(Parent.CustomerCountry = 'US', 'US', 'Foreign Country')");

// Find an Order Details Row, just to start things off
DataRow row = ds.Tables["Order Details"].Rows.Find(new object[] {"10260", "57"});

// Look at the expression column
Debug.WriteLine(row["CountryType"]);

The second solution does not require expression columns. Instead, it uses the GetParentRow method of the DataRow. In this example, I evaluate the Customers.Country field by travelling up from the Order Details row to its parent Orders row and then up to its grandparent Customers row. Grandparent via GetParentRow
// Use the GetParentRow to get the value instead
string sCountry = row.GetParentRow("O2OD").GetParentRow("C2O")["Country"].ToString();
Debug.WriteLine((sCountry == "US")   ? "US" : "Foreign Country");

Read: Getting GrandParent columns with ADO.NET


Topic: Patterns and Practices Live Previous Topic   Next Topic Topic: New VB IDE team blog

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use