[ Team LiB ] |
Recipe 5.2 Copying Tables from One DataSet to AnotherProblemYou need to copy an existing schema and data from one DataSet to another. SolutionUse one of the following techniques:
Once the destination tables are created and the data is copied into them, the example shows how to create the DataRelation objects from the source DataSet in the destination DataSet. The sample code contains two event handlers:
The C# code is shown in Example 5-2. Example 5-2. File: CopyTablesBetweenDataSetsForm.cs// Namespaces, variables, and constants using System; using System.Configuration; using System.Windows.Forms; using System.Data; using System.Data.SqlClient; // Table name constants private const String ORDERS_TABLE = "Orders"; private const String ORDERDETAILS_TABLE = "OrderDetails"; // Relation name constants private const String ORDERS_ORDERDETAILS_RELATION = "Orders_OrderDetails_Relation"; // Field name constants private const String ORDERID_FIELD = "OrderID"; private const String ORDERDATE_FIELD = "OrderDate"; private const String EMPLOYEEID_FIELD = "EmployeeID"; private DataSet dsSource; // . . . private void CopyTablesBetweenDataSetsForm_Load(object sender, System.EventArgs e) { dsSource = new DataSet("Source"); SqlDataAdapter da; // Fill the Order table and add it to the DataSet. da = new SqlDataAdapter("SELECT * FROM Orders", ConfigurationSettings.AppSettings["Sql_ConnectString"]); DataTable orderTable = new DataTable(ORDERS_TABLE); da.FillSchema(orderTable, SchemaType.Source); da.Fill(orderTable); dsSource.Tables.Add(orderTable); // Fill the OrderDetails table and add it to the DataSet. da = new SqlDataAdapter("SELECT * FROM [Order Details]", ConfigurationSettings.AppSettings["Sql_ConnectString"]); DataTable orderDetailTable = new DataTable(ORDERDETAILS_TABLE); da.FillSchema(orderDetailTable, SchemaType.Source); da.Fill(orderDetailTable); dsSource.Tables.Add(orderDetailTable); // Create a relation between the tables. dsSource.Relations.Add(ORDERS_ORDERDETAILS_RELATION, dsSource.Tables[ORDERS_TABLE].Columns[ORDERID_FIELD], dsSource.Tables[ORDERDETAILS_TABLE].Columns[ORDERID_FIELD], true); // Bind the source and destination DataSet to the grids. sourceDataGrid.DataSource = dsSource.Tables[ORDERS_TABLE].DefaultView; } private void copyButton_Click(object sender, System.EventArgs e) { // Create the destination DataSet into which to copy tables DataSet dsDest = new DataSet("Destination"); if (copyAllRadioButton.Checked) { foreach(DataTable sourceTable in dsSource.Tables) { // First technique: when all rows need to be copied dsDest.Tables.Add(sourceTable.Copy( )); } } else if (copySubsetRadioButton.Checked) { int employeeId = 0; try { employeeId = Convert.ToInt32(employeeIdTextBox.Text); } catch (Exception ex) { MessageBox.Show(ex.Message); return; } // Second technique: can be used to import subset foreach(DataTable dtSource in dsSource.Tables) { // Add logic to selectively copy tables. dsDest.Tables.Add(dtSource.Clone( )); } // Copy rows for selected employee from the Orders table. foreach(DataRow parentRow in dsSource.Tables[ORDERS_TABLE].Select( EMPLOYEEID_FIELD + "=" + employeeId)) { dsDest.Tables[ORDERS_TABLE].ImportRow(parentRow); // Copy the Order Details for the Order. foreach(DataRow childRow in parentRow.GetChildRows( ORDERS_ORDERDETAILS_RELATION)) { dsDest.Tables[ ORDERDETAILS_TABLE].ImportRow(childRow); } } } // Create the relations in the destination DataSet. // Iterate over the collection of relations in the source. foreach(DataRelation sourceRelation in dsSource.Relations) { // Get the name of the parent and child table for the relation. String parentTableName = sourceRelation.ParentTable.TableName; String childTableName = sourceRelation.ChildTable.TableName; // Get the number of parent columns for the source relation. int nCol = sourceRelation.ParentColumns.Length; // Create an array of parent columns in the destination. DataColumn[] parentCols = new DataColumn[nCol]; for(int i = 0; i < nCol; i++) parentCols[i] = dsDest.Tables[parentTableName].Columns[ sourceRelation.ParentColumns[i].Ordinal]; // Create an array of child columns in the destination. DataColumn[] childCols = new DataColumn[nCol]; for(int i = 0; i < nCol; i++) childCols[i] = dsDest.Tables[childTableName].Columns[ sourceRelation.ChildColumns[i].Ordinal]; // Create the relation in the destination DataSet. dsDest.Relations.Add( new DataRelation(sourceRelation.RelationName, parentCols, childCols, false)); } // Set the enforce constraints flag to match the source DataSet. dsDest.EnforceConstraints = dsSource.EnforceConstraints; // Bind the default view of the Orders table to the grid. destDataGrid.DataSource = dsDest.Tables[ORDERS_TABLE].DefaultView; } DiscussionThis sample demonstrates two scenarios for copying tables from one DataSet to another. In the first scenario, all of the data and tables in the source DataSet are copied to the destination. This is accomplished by iterating over the collection of tables in the source DataSet and using the Copy( ) method of each DataTable object to copy both the schema and data for each table into the destination DataSet. In the second scenario, only a subset of the data in the source DataSet is copied to the destination. Since there is a relation in place between the Orders and Order Details tables in this case, only the child records related to the selected parent records are copied to the destination. Once the data has been copied, the DataRelation objects are copied by iterating over the collection of DataRelation objects in the source DataSet, and adding them to the destination DataSet. This involves creating an array of parent and source columns for the destination DataRelation from the parent and child column ordinals in the source DataRelation. This information, together with the name of the source DataRelation is used to create the DataRelation in the destination DataSet. Finally, the EnforceConstraints property in the destination DataRelation is set to match the source. |
[ Team LiB ] |