[ Team LiB ] Recipe 3.14 Using theShapeLanguagetoRetrieveHierarchicalData Problem You want to use theShapelanguage with ADO.NET toretrievehierarchicaldata from a SQL Server. Solution Execute theSHAPE command as shown in the following example usingthe OLE DB provider. The sample code defines a SHAPE query toretrievethe TOP 5 Orders from Northwind and the Order Details for each of the Orders. A DataReader based on the query is created. The code iterates over the rows in the DataReader displaying thedata for each Order row. If the value for the column can be cast tothe IDataReader interface, it is a DataReader containing the Order Details for the Order row. The value for the column is cast to a DataReader and the collection of records is iterated over and displayed. The C# code is shown in Example 3-14 . Example 3-14. File: ShapeForm.cs // Namespaces, variables, and constants using System; using System.Configuration; using System.Text; using System.Data; using System.Data.OleDb; // . . . StringBuilder result = new StringBuilder( ); // SHAPE SQL toretrieve TOP five Orders and associated Order Detail records. String shapeText = "SHAPE {select TOP 5 * from Orders} AS Orders " + "APPEND ({select * from [Order Details]} AS 'Order Details' " + "RELATE OrderID TO OrderID)"; // Create the connection. OleDbConnection conn = new OleDbConnection( ConfigurationSettings.AppSettings["OleDb_Shape_ConnectString"]); // Create a command and fill a DataReader with the // SHAPE result set. OleDbCommand cmd = new OleDbCommand(shapeText, conn); conn.Open( ); OleDbDataReader orderDR = cmd.ExecuteReader( ); // Iterate over the collection of rows in the DataReader. while(orderDR.Read( )) { result.Append("ORDER" + Environment.NewLine); // Iterate over the collection of Order columns in the DataReader. for(int colOrder = 0; colOrder < orderDR.FieldCount; colOrder++) { if (orderDR[colOrder] is IDataReader) { // The column is an IDataReader interface. result.Append(Environment.NewLine); result.Append(orderDR.GetName(colOrder).ToUpper( ) + Environment.NewLine); // Create a DataReader for the Order Detail from the // IDataReader interface column. OleDbDataReader orderDetailDR = (OleDbDataReader)orderDR.GetValue(colOrder); // Iterate over records in the Order Detail DataReader. while(orderDetailDR.Read( )) { // Iterate over the Order Detail columns // in theData Reader. for(int colOrderDetail = 0; colOrderDetail < orderDetailDR.FieldCount; colOrderDetail++) { result.Append(" " + orderDetailDR.GetName(colOrderDetail) + ": " + orderDetailDR[colOrderDetail] + Environment.NewLine); } result.Append(Environment.NewLine); } } else { result.Append(orderDR.GetName(colOrder)+ ": " + orderDR[colOrder] + Environment.NewLine); } } result.Append(Environment.NewLine); } orderDR.Close( ); conn.Close( ); resultTextBox.Text = result.ToString( ); Discussion You can retrievehierarchical result sets or chapters (OLE DB type DBTYPE_HCHAPTER) from SQL Server usingthe OLE DB .NET data provider. The chapter is returned as a field in thedata reader with a data type of Object that is a DataReader. Hierarchical result sets combine the results for multiple queries into a single structure. They are generated usingtheData Shaping Service for OLE DB first introduced in ADO 2.0. This provider supports theShapelanguage allowing the result set hierarchies to be constructed. Shaping is an alternative to JOIN and GROUP BY syntax that you can use to access parent/child data and associated summary data. The connection string usingdata shaping is shown here: Provider=MSDataShape;Data Provider=SQLOLEDB;Data Source=(local); Initial Catalog=Northwind;Integrated Security=SSPI; For more information about data shaping or the MSDataShape provider, see the MSDN library. [ Team LiB ] . Recipe 3.14 Using the Shape Language to Retrieve Hierarchical Data Problem You want to use the Shape language with ADO.NET to retrieve hierarchical data from. Solution Execute the SHAPE command as shown in the following example using the OLE DB provider. The sample code defines a SHAPE query to retrieve the TOP 5 Orders