Microsoft KB Archive/313028

= How to fill a DataSet from a data source and update another data source by using Visual C# .NET =

Article ID: 313028

Article Last Modified on 1/6/2006

-

APPLIES TO


 * Microsoft ADO.NET 1.0
 * Microsoft ADO.NET 1.1
 * Microsoft Visual C# .NET 2002 Standard Edition
 * Microsoft Visual C# .NET 2003 Standard Edition

-



This article was previously published under Q313028



For a Microsoft Visual Basic .NET version of this article, see 310347.

This article refers to the following Microsoft .NET Framework Class Library namespace:
 * System.Data.SqlClient

IN THIS TASK
SUMMARY Description of the technique Create a new Authors table in the Northwind database and a new Visual C# project Update a Data Source Other Than the Original Data Source
 * Update all records to an empty table using the CommandBuilder
 * Update all records to an empty table Using TSQL commands
 * Update only the changed records to a different table
 * Update only the changed records to both tables

Troubleshooting REFERENCES



SUMMARY
ADO.NET provides new flexibility in how you update your data source. This article describes how you can update a data source that is different from the original data source that you use to create the DataSet object.

back to the top

Description of the technique
Earlier versions of Microsoft ActiveX Data Objects (ADO) allow you to update records in a data source other than the original data source of those records, though this is difficult to do. Because ADO.NET is a truly disconnected model and because ADO.NET introduces the DataAdapter object, you can more easily update a data source with information from another data source.

You can use the InsertCommand, UpdateCommand, and DeleteCommand properties of DataAdapter to update the data source with modifications that are made to the DataSet object. These properties contain the INSERT, UPDATE, and DELETE SQL commands respectively. You can use these commands to post the modifications back to the target data source. You can use any of the following methods to create these commands:
 * Manually create the commands in code.
 * Use the CommandBuilder object to automatically generate the commands.
 * Use the DataAdapter Wizard to visually generate the commands.

This article includes samples for the first two methods.

This article describes four ways to update records in a data source other than the original data source of those records. To successfully run the sample code, you must first create the Visual C# project. After you complete the steps in the Create a New Authors Table in the Northwind database and a New Visual C# Project section, you can proceed to any of the other sections.

back to the top

Create a new Authors table in the Northwind database and a new Visual C# project
Each of the samples in this article requires a Visual C# project and a new table in the sample Northwind database.

Note In the code to fill the DataSet with the records from the Authors table, you can also insert the data in a different data source. To insert the data in a different data source, you must set the AcceptChangesDuringFill property to False. When you set AcceptChangesDuringFill to False, the AcceptChanges method of the DataRow object is not called when a row is added to the data table. Therefore, for each row that is added to the data table, the RowState property value is Added instead of Unchanged.

As a result, when the DataSet is submitted to the Update method of a DataAdpater, DataSet invokes the INSERT command of the DataAdapter instead of the UPDATE command for each of the DataRow objects. For more information, refer to the REFERENCES section.

To create a Visual C# project and a new table in the Northwind database, follow these steps:   Open Query Analyzer, and then select the Northwind database. Run the following SQL script to create the Authors table: CREATE TABLE [dbo].[authors] (   [au_id] [varchar] (11) primary key NOT NULL,    [au_lname] [varchar] (40) NOT NULL ,    [au_fname] [varchar] (20) NOT NULL ,    [phone] [char] (12) NULL ,    [address] [varchar] (40) NULL ,    [city] [varchar] (20) NULL ,    [state] [char] (2) NULL ,    [zip] [char] (5) NULL ,    [contract] [bit] NULL ) ON [PRIMARY] GO  Start Visual Studio .NET, and then create a new Windows Application in Visual C# .NET.  Add the following code to the top of the Code window. This code allows you to use the objects of these namespaces without fully qualifying them. using System.Data.SqlClient; using System.Data;   At the top of Public Class Form1, add the following declaration statements: SqlConnection PubConn; SqlConnection NWindConn; SqlCommand PubCom; DataSet dsPub; SqlDataAdapter daPub;   Double-click the form to display the Form_Load event in the Code window. Add the following code to this event to open the connection to the Authors table in the Pubs database and to fill the DataSet, dsPub, with the records from the Authors table: PubConn = new SqlConnection (&quot;server=server;uid=sa;pwd=password;initial catalog=pubs;&quot;); NWindConn = new SqlConnection (&quot;server=server;uid=sa;pwd=password;initial catalog=northwind;&quot;); PubCom = new SqlCommand (&quot;Select * from authors&quot;, PubConn); dsPub = new DataSet; daPub = new SqlDataAdapter; PubConn.Open; daPub.SelectCommand = PubCom; daPub.AcceptChangesDuringFill = false; daPub.Fill (dsPub, &quot;Authors&quot;);   Modify the server, the uid, and the password arguments in the following code to point to the computer that is running Microsoft SQL Server: PubConn = new SqlConnection (&quot;server=server;uid=sa;pwd=password;initial catalog=pubs;&quot;); NWindConn = new SqlConnection (&quot;server=server;uid=sa;pwd=password;initial catalog=northwind;&quot;);  Add two TextBox controls (TextBox1 and TextBox2) to Form1.</li> Add a Button control to Form1. Change the Name property to btnEdit, and then change the Text property to Edit .</li>  Double-click the button to display the btnEdit_Click event in the Code window. Add the following code to this event: Console.Write (dsPub.Tables[&quot;Authors&quot;].Rows[1][1]); Console.Write (dsPub.Tables[&quot;Authors&quot;].Rows[1][2]); dsPub.Tables [&quot;Authors&quot;].Rows[1].BeginEdit; dsPub.Tables[&quot;Authors&quot;].Rows[1][1] = textBox2.Text; dsPub.Tables[&quot;Authors&quot;].Rows[1][2] = textBox1.Text; dsPub.Tables[&quot;Authors&quot;].Rows[1].EndEdit; Console.Write (dsPub.Tables[&quot;Authors&quot;].Rows[1][1]); Console.Write (dsPub.Tables[&quot;Authors&quot;].Rows[1][2]); This code writes the original value of the second author's first and last names in the DataSet to the Output window. The code edits the author's first and last name fields and then finally writes the new values to the Output window to confirm that they have been changed in the DataSet. Notice that the code does not update the information back to the data source. This code only edits the DataSet object. </li></ol>

back to the top

Update a data source other than the original data source
This section describes four different ways to update records in a data source other than the original data source of those records.

back to the top

Update all records to an empty table using the CommandBuilder
This section demonstrates one way to update a data source with information from another data source. In this sample, you create a DataSet from the Authors table in the Pubs database, edit a record in that DataSet, and commit the changed records and all other records to an empty Authors table in the Northwind database. You do not update any changes back to the original Pubs database.

This sample uses two DataAdapter objects, one DataSet object, and the CommandBuilder object. You use the first DataAdapter to create a DataSet based on the Authors table in the Pubs database. You connect the second DataAdapter to the Authors table in the Northwind database, and you use this DataAdapter for updating. Finally, you use the CommandBuilder object to create the Transact SQL (TSQL) commands that are necessary to update and to insert records into the data source. <ol> Complete the steps in the Create a New Authors Table in the Northwind Database and a New Visual C# Project section to set up the Authors table in the Northwind database and to create the Visual C# .NET project.</li> Make sure that no records exist in the Authors table of the Northwind database. This can occur when you set DataAdapter.AcceptChangesDuringFill to False. If records exist in the Authors table, you receive a primary key violation when you run this code because you insert duplicate values.</li> Add a Button control to Form1. Change the Name property to btnUpdate1, and then change the Text property to Update1 .</li>  Double-click Update1 to display the Code window and the btnUpdate1_click event. Add the following code to this event: SqlDataAdapter NwindDA = new SqlDataAdapter (&quot;Select * from authors&quot;, NWindConn); SqlCommandBuilder x = new SqlCommandBuilder (NwindDA); NWindConn.Open; NwindDA.Update(dsPub, &quot;Authors&quot;); Console.Write(&quot;Done&quot;); This code creates a new DataAdapter object that works with the second Authors table. This DataAdapter object then uses the CommandBuilder object to create the TSQL commands. </li> Run the application.</li> Type a new first name in TextBox1, type a new last name in TextBox2, and then click Edit. This edits the records in the dsPubDataSet. This also displays the original values of the first name and the last name fields in the Output window, along with the new values for these same fields.</li> Click Update1. After &quot;Done&quot; appears in the Output window, stop running the application.</li> Open the Authors table in the Northwind database. Notice that the Authors table contains all of the records from the original table. In addition, the second record includes the values that you typed in the text boxes.</li> Refer to the original Authors table in the Pubs database. Notice that the values for the second record are not changed.</li></ol>

back to the top

Update all records to an empty table by using TSQL commands
This sample allows you to move all of the records from the Authors table in the Pubs database to an empty Authors table in the Northwind database without changing the original table. To perform these updates, you manually create TSQL commands and then use these TSQL commands on the DataAdapter object. This method provides better performance than the CommandBuilder object method. <ol> Complete the steps in the Create a new Authors table in the Northwind database and a New Visual C# project section to set up the Authors table in the Northwind database and to create the Visual C# .NET project.</li> Make sure that no records exist in the Authors table of the Northwind database. This can occur when you set DataAdapter.AcceptChangesDuringFill to False. If records exist in the Authors table, you receive a primary key violation when you run this code because you insert duplicate values.

Even though a row is edited, you only need an InsertCommand property because all of the rows are flagged as Added due to the setting of AcceptChangesDuringFill.</li> Add a Button control to Form1. Change the Name property to btnUpdate2, and then change the Text property to Update2 .</li>  Double-click Update2 to display the Code window and the btnUpdate2_click event. Add the following code to this event: SqlDataAdapter NWindDA = new SqlDataAdapter (&quot;Select * from Authors&quot;, NWindConn);

NWindDA.UpdateCommand = new SqlCommand (&quot;Update Authors Set au_lname=@lastname where au_id = @au_id&quot;,     NWindConn);

SqlParameter workParam = NWindDA.UpdateCommand.Parameters.Add (&quot;@auID&quot;, SqlDbType.VarChar, 11); workParam.SourceColumn = &quot;au_ID&quot;; workParam.SourceVersion = DataRowVersion.Original ;

SqlParameter workParam4 = NWindDA.UpdateCommand.Parameters.Add (&quot;@lastname&quot;, SqlDbType.NVarChar,15); workParam4.SourceColumn = &quot;au_lname&quot;; workParam4.SourceVersion = DataRowVersion.Current;

NWindDA.InsertCommand = new SqlCommand (&quot;Insert into authors (au_id, au_lname, au_fname) &quot; +     &quot;Values (@au_id, @au_lname, @au_fname)&quot;, NWindConn); SqlParameter workParam1 = NWindDA.InsertCommand.Parameters.Add (&quot;@au_id&quot;, SqlDbType.VarChar,11); workParam1.SourceColumn = &quot;au_ID&quot;;

SqlParameter workParam2 = NWindDA.InsertCommand.Parameters.Add (&quot;@au_lname&quot;, SqlDbType.VarChar,40); workParam2.SourceColumn = &quot;au_lname&quot;;

SqlParameter workParam3 = NWindDA.InsertCommand.Parameters.Add (&quot;@au_fname&quot;, SqlDbType.VarChar,20); workParam3.SourceColumn = &quot;au_fname&quot;; NWindConn.Open; NWindDA.Update (dsPub,&quot;Authors&quot;); Console.Write (&quot;Done&quot;); This code creates a new DataAdapter object that works with the Authors table in the Northwind database. This DataAdapter then uses TSQL commands that you manually create. </li> <li>Run the application.</li> <li>Type a first name in TextBox1, type a last name in TextBox2, and then click Edit. This edits the records in the dsPubDataSet. This also displays the original values of the first name and the last name fields in the Output Window, along with the new values for these same fields.</li> <li>Click Update2.</li> <li>After &quot;Done&quot; appears in the Output window, open the Authors table in the Northwind database. Notice that the Authors table contains all of the records from the original Authors table. In addition, the second record includes the new values.</li> <li>Refer to the original Authors table in the Pubs database. Notice that the values for the second record are not updated because you called the Update method of the DataAdapter that is configured for the Northwind database.</li></ol>

back to the top

Update only the changed records to a different table
In this sample, you send only the updated records to the Northwind database. This sample updates the data source by using the GetChanges method to pull the modified row or rows out of the original DataSet. The sample inserts the row or rows into a temporary DataSet named ChangedDS. The sample then calls the Update method of the DataAdapter object to pass this temporary DataSet to the Northwind database. Finally, the sample calls the AcceptChanges method of the working DataSet, dsPub, to bring dsPub to a consistent state to reflect the data source changes. <ol> <li>Complete the steps in the Create a new Authors table in the Northwind database and a New Visual C# project section to set up the Authors table in the Northwind database and to create the Visual C# .NET project.</li> <li>Make sure that the Authors table in the Northwind database contains at least the second row from the Authors table in the Pubs database. This is the row that you will edit and use for the update.

If the Authors table in the Northwind database does not contain this row, you can run the code from the Update all records to an empty table by using the CommandBuilder section to add all of the records to this table. You can also add the records manually.</li> <li> Locate the following line of code in the Form_Load event: 'daPub.AcceptChangesDuringFill = False Comment out this line so that it appears as follows: //daPub.AcceptChangesDuringFill = False This inserts the rows into the DataSet as existing rows. </li> <li>Add a new Button control to Form1. Change the Name property to btnUpdate3, and then change the Text property to Update3 .</li> <li> Double-click Update3 to display the btnUpdate3_click event. Add the following code to this event: SqlDataAdapter NWindDA = new SqlDataAdapter (&quot;Select * from Authors&quot;, NWindConn);

NWindDA.UpdateCommand = new SqlCommand (&quot;Update Authors Set au_lname = @lastname, au_fname=@au_fname where       au_ID=@auid&quot;, NWindConn); SqlParameter workParam = NWindDA.UpdateCommand.Parameters.Add (&quot;@auID&quot;, SqlDbType.VarChar, 11); workParam.SourceColumn = &quot;au_ID&quot;; workParam.SourceVersion = DataRowVersion.Original;

SqlParameter workParam4 = NWindDA.UpdateCommand.Parameters.Add (&quot;@lastname&quot;, SqlDbType.NVarChar, 15); workParam4.SourceColumn = &quot;au_lname&quot;; workParam4.SourceVersion = DataRowVersion.Current;

SqlParameter workParam1 = NWindDA.UpdateCommand.Parameters.Add (&quot;@au_fname&quot;, SqlDbType.VarChar, 11); workParam1.SourceColumn = &quot;au_fname&quot;; workParam1.SourceVersion = DataRowVersion.Current;

NWindConn.Open; DataSet changedDS; changedDS = dsPub.GetChanges(DataRowState.Modified); NWindDA.Update(changedDS, &quot;Authors&quot;); Console.Write (&quot;Done&quot;); dsPub.AcceptChanges; </li> <li>Run the application.</li> <li>Type a first name in TextBox1, type a last name in TextBox2, and then click Edit. This edits the records in the dsPubDataSet. This also displays the original values of the first name and the last name fields in the Output window, along with the new values for these same fields.</li> <li>Click Update3.</li> <li>After &quot;Done&quot; appears in the Output window, open the Authors table in the Northwind database. Notice that the Authors table contains the changes that you made to the DataRow.</li> <li>Refer to the original Authors table in the Pubs database. Notice that the values for the second record are not updated.</li></ol>

back to the top

Update only the changed records to both tables
To update the records in both data sources, you can use two DataAdapter objects and the GetChanges method of the DataSet object. In this sample, you create a DataSet object based on the Authors table in the Pubs database. You edit this DataSet and then copy the changed records into a new DataSet object. You use this new DataSet to update the tables of the data source. After you update the table of the first data source, you call the GetChanges method again and re-create the temporary DataSet. You can then update the table of the second data source.

In this sample, you use the temporary DataSet and call GetChanges twice because the Update method of the DataAdapter implicitly calls AcceptChanges on the DataSet that you pass to it. The implicit AcceptChanges method resynchronizes the original and the current values for each cell that is changed. In addition, the implicit AcceptChanges method flags the DataRow as UnModified. This eliminates the changes and prevents you from sending the changes to another data source.

In this particular instance, you can skip the second GetChanges method and pass the original DataSet to the Update method of the Pubs DataAdapter. This eliminates the dsPubs.AcceptChanges call. However, the combination of the temporary DataSet and the GetChanges method allows you to roll back to the original modifications. In earlier versions of Microsoft ActiveX Data Objects (ADO), you persist the recordset to a file to achieve this functionality. <ol> <li>Complete the steps in the Create a new authors table in the Northwind database and a New Visual C# project section to set up the Authors table in the Northwind database and to create the Visual C# .NET project.</li> <li>Make sure that the Northwind database contains an Authors table, and make sure that this Authors table contains at least the record that you will modify from the Authors table in the Pubs database.</li> <li> Locate the following line of code in the Form_Load event: 'daPub.AcceptChangesDuringFill = False Comment out this line so that it appears as follows: //daPub.AcceptChangesDuringFill = False </li> <li>Add a Button control to Form1. Change the Name property to btnUpdate4, and then change the Text property to Update4 .</li> <li> Double-click Update4 to display the btnUpdate4_click event. Add the following code to this event: SqlDataAdapter NWindDA = new SqlDataAdapter (&quot;Select * from Authors&quot;, NWindConn);

NWindDA.UpdateCommand = new SqlCommand (&quot;UPDATE authors SET au_lname = @lastName, au_fname = @au_fname&quot; +       &quot; WHERE au_ID = @auID&quot;, NWindConn);

SqlParameter workParam = NWindDA.UpdateCommand.Parameters.Add (&quot;@auID&quot;, SqlDbType.VarChar, 11); workParam.SourceColumn = &quot;au_ID&quot;; workParam.SourceVersion = DataRowVersion.Original;

SqlParameter workparam4 = NWindDA.UpdateCommand.Parameters.Add (&quot;@lastName&quot;, SqlDbType.NVarChar, 15); workparam4.SourceColumn = &quot;au_lname&quot;; workparam4.SourceVersion = DataRowVersion.Current;

SqlParameter workParm3 = NWindDA.UpdateCommand.Parameters.Add (&quot;@au_fname&quot;, SqlDbType.VarChar, 20); workParm3.SourceColumn = &quot;au_fname&quot;; workParm3.SourceVersion = DataRowVersion.Current;

NWindConn.Open;

daPub.UpdateCommand = new SqlCommand (&quot;UPDATE authors SET au_lname = @lastName, au_fname = @au_fname&quot; +       &quot; WHERE au_ID = @auID&quot;, PubConn);

SqlParameter workParm7 = daPub.UpdateCommand.Parameters.Add (&quot;@auID&quot;, SqlDbType.VarChar, 11); workParm7.SourceColumn = &quot;au_ID&quot;; workParm7.SourceVersion = DataRowVersion.Original;

SqlParameter workparm8 = daPub.UpdateCommand.Parameters.Add (&quot;@lastName&quot;, SqlDbType.NVarChar, 15); workparm8.SourceColumn = &quot;au_lname&quot;; workparm8.SourceVersion = DataRowVersion.Current;

SqlParameter workParm11 = daPub.UpdateCommand.Parameters.Add (&quot;@au_fname&quot;, SqlDbType.VarChar, 20); workParm11.SourceColumn = &quot;au_fname&quot;; workParm11.SourceVersion = DataRowVersion.Current;

DataSet changedDS = new DataSet; changedDS = dsPub.GetChanges(DataRowState.Modified);

NWindDA.Update(changedDS, &quot;Authors&quot;); changedDS = dsPub.GetChanges(DataRowState.Modified);

daPub.Update(changedDS, &quot;Authors&quot;); dsPub.AcceptChanges;

Console.Write(&quot;Done&quot;); </li> <li>Run the application.</li> <li>Type a new first name in TextBox1, type a new last name in TextBox2, and then click Edit. This edits the records in the dsPubDataSet. This also displays the original values of the first name and the last name fields in the Output window, along with the new values for these same fields.</li> <li>Click Update4.</li> <li>After &quot;Done&quot; appears in the Output window, open the Authors table in the Pubs database and the Authors table in the Northwind database. Notice that both tables include the new values for the second record.</li></ol>

back to the top

Troubleshooting
When you work with the code in the Update only the changed records to a different table and Update only the changed records to both tables sections, you may receive a System.ArgumentNullException error. If this occurs, locate the following line of code: 'daPub.AcceptChangesDuringFill = False Make sure that this line of code is commented out and appears as follows: \\daPub.AcceptChangesDuringFill = False This line of code tells the DataAdapter to call the AcceptChanges method when the Fill method of the DataAdapter is called.

back to the top

<div class="references_section">