[ Team LiB ] |
Recipe 5.6 Merging DataProblemYou have two DataSet objects with the same schema, but containing different data. You need to combine data from these two DataSet objects without creating duplicate rows. SolutionUse the DataSet.Merge( ) method with the appropriate MissingSchemaAction enumeration values. The sample code contains four event handlers and a single method:
The C# code is shown in Example 5-6. Example 5-6. File: MergingDataForm.cs// Namespaces, variables, and constants using System; using System.Configuration; using System.Windows.Forms; using System.Data; using System.Data.SqlClient; private SqlDataAdapter daA, daB; private DataSet dsA, dsB; // . . . private void MergingDataForm_Load(object sender, System.EventArgs e) { // Fill the schema and data for table A. String sqlText = "SELECT EmployeeID, LastName, FirstName, Title " + "FROM Employees WHERE EmployeeID BETWEEN 1 AND 5"; // Set up the DataAdapter and CommandBuilder for table A. SqlCommandBuilder cbA = new SqlCommandBuilder(daA); daA = new SqlDataAdapter(sqlText, ConfigurationSettings.AppSettings["Sql_SqlAuth_ConnectString"]); // Define DataSet A and fill its table A with schema and data. dsA = new DataSet("A"); daA.FillSchema(dsA, SchemaType.Source, "Employees"); daA.Fill(dsA, "Employees"); // Bind the default view for table A to the grid. dataGridA.DataSource = dsA.Tables["Employees"].DefaultView; // Fill the schema and data for table B. sqlText = "SELECT EmployeeID, LastName, FirstName, " + "BirthDate, HireDate " + "FROM Employees WHERE EmployeeID BETWEEN 4 AND 8"; // Set up the DataAdapter and CommandBuilder for table B. daB = new SqlDataAdapter(sqlText, ConfigurationSettings.AppSettings["Sql_SqlAuth_ConnectString"]); SqlCommandBuilder cbB = new SqlCommandBuilder(daB); // Define DataSet B and fill its table B with schema and data. dsB = new DataSet("B"); daB.FillSchema(dsB, SchemaType.Source, "Employees"); daB.Fill(dsB, "Employees"); // Bind the default view for table B to the grid. dataGridB.DataSource = dsB.Tables["Employees"].DefaultView; } private void Merge(DataTable dtSource, DataTable dtDest) { // Set the missing schema value to the default and read // actual value, if otherwise, from the radio buttons. MissingSchemaAction msa = MissingSchemaAction.Add; if(addWithKeyRadioButton.Checked) msa = MissingSchemaAction.AddWithKey; else if(errorRadioButton.Checked) msa = MissingSchemaAction.Error; else if(ignoreRadioButton.Checked) msa = MissingSchemaAction.Ignore; // Create the merge DataSet and copy table B into it. DataSet ds = new DataSet("Merge"); ds.Tables.Add(dtDest.Copy( )); try { // Merge table A into the DataSet. ds.Merge(dtSource, false, msa); } catch (Exception ex) { MessageBox.Show(ex.Message); } // Bind the merge result table default view to the grid. dataGridMerge.DataSource = ds.Tables[0].DefaultView; dataGridMerge.CaptionText = "Merge Results: " + dtSource.DataSet.DataSetName + " into " + dtDest.DataSet.DataSetName; } private void mergeAIntoBButton_Click(object sender, System.EventArgs e) { Merge(dsA.Tables["Employees"], dsB.Tables["Employees"]); } private void mergeBIntoAButton_Click(object sender, System.EventArgs e) { Merge(dsB.Tables["Employees"], dsA.Tables["Employees"]); } private void clearResultsButton_Click(object sender, System.EventArgs e) { dataGridMerge.DataSource = null; dataGridMerge.CaptionText = ""; } DiscussionThe Merge( ) method of the DataSet can merge a DataRow array, a DataTable, or a DataSet into an existing DataSet. If the existing DataSet has a primary key defined, the incoming data is matched to rows having the same primary key values. Where matches are found, the existing row is updated with the new values. Otherwise, rows are appended to the existing table. There are two arguments that can be optionally specified in the overloaded Merge( ) methods. The first, preserveChanges, is a Boolean value that indicates whether incoming values will overwrite changes made to the existing DataSet. If preserveChanges is false, the default, both the Current and Original row are overwritten with incoming values and the RowState of the row is set to the RowState of the incoming row. Exceptions are shown in Table 5-2.
If preserveChanges is specified as true, the values in the Current version of the existing row are maintained while values in the Original version of the existing row are overwritten with the Original values for the incoming row. The RowState of the existing row is set to Modified. Exceptions are shown in Table 5-3.
The second argument is the missingSchemaAction argument, which accepts a value from the MissingSchemaAction enumeration that specifies how the Merge( ) method will handle schema elements in the incoming data that are not part of the existing DataSet. Table 5-4 describes the values in the MissingSchemaAction enumeration.
|
[ Team LiB ] |