Solution Use one of the following techniques: • Use the Copy method of the DataTable when all of the data for a table needs to be copied.. • Use the Clone method of the DataTable t
Trang 1[ Team LiB ]
Recipe 5.2 Copying Tables from One DataSet to Another
Problem
You need to copy an existing schema and data from one DataSet to another
Solution
Use one of the following techniques:
• Use the Copy( ) method of the DataTable when all of the data for a table needs to
be copied
• Use the Clone( ) method of the DataTable to create the schema for each table in the destination DataSet when only a subset of the data needs to be copied You can use the ImportRows( ) method of the DataTable to copy the subset of rows from the source to the destination table
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:
Form.Load
Sets up the sample by creating a DataSet containing the Orders and Order Details tables from Northwind and a relation between the two tables The default view for the Orders table is bound to a data grid on the form
Copy Button.Click
Creates a destination DataSet and copies the schema and specified data into it from the source DataSet created in the Form.Load event handler
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;
Trang 2using 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);
Trang 3// 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( ));
Trang 4}
// 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];
Trang 5// 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;
}
Discussion
This 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 ]