I'm going to assume that you know basically how DataAdapters work and how to fill a dataset with them. So what happens after you fill your dataset. Typicall, you start making changes to that data. You might modify a value in a row for instance. You might delete a row. You might add a row. And at some point, you call the Update method of the dataadapter and if all works well, the changes in the dataset are committed to your database.
We know that if you use the visual tools, when you configure a dataadapter, you choose a connection, then choose a table(s), pick your fields and hit Next. At this point, you'll be told what succeeded - the possibilities are Update Command Succeeded, Insert Command Succeeded , Delete Command Succeeded and Select Command Succeeded. As long as you have a valid Key on your table and aren't using any joins, this works 99% of the time.
Now you'll typically fill a dataset, modify the data and then submit an update. Very simple. But how does calling DataAdapter.Update cause the update to happen. To understand this you need to take a look at the logic that's generated:
A Typical Snippet looks something like this:
| this.sqlUpdateCommand1.CommandText = "UPDATE Employees SET LastName = @LastName, FirstName = @FirstName, Title = @Title" +", TitleOfCourtesy = @TitleOfCourtesy, BirthDate = @BirthDate, HireDate = @HireDa" +"te, Address = @Address, City = @City, Region = @Region, PostalCode = @PostalCode" + ", Country = @Country, HomePhone = @HomePhone, Extension = @Extension, Photo = @P" +"hoto, Notes = @Notes, |
| this.sqlUpdateCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@LastName", System.Data.SqlDbType.NVarChar, 20, "LastName")); this.sqlUpdateCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@FirstName", System.Data.SqlDbType.NVarChar, 10, "FirstName")); this.sqlUpdateCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Title", System.Data.SqlDbType.NVarChar, 30, "Title")); this.sqlUpdateCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@TitleOfCourtesy", System.Data.SqlDbType.NVarChar, 25, "TitleOfCourtesy")); this.sqlUpdateCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@BirthDate", System.Data.SqlDbType.DateTime, 8, "BirthDate")); |
private void cn_StateChange(object sender, System.Data.StateChangeEventArgs e) { MessageBox.Show("Connection State is Currently: " + e.CurrentState.ToString()); } private void btnProve_Click(object sender, System.EventArgs e) { ds = new DataSet(); da.Fill(ds, "TestTable"); //Just filled table, rowstate is Unchanged for all rows //Now, we'll prove that if the DataSet HasChanges == false //Calling update all year does NOTHING! //Keep your eye on the StateChanged Event Handler..it'll only //fire once when it opens the connection for fill, and once //more when it closes it. Never during the loop Debug.Assert(!ds.HasChanges(), "Changes are present"); for(int x = 0; x < 1000; x++)<BR> { da.Update(ds.Tables[0]); } } |
| private void btnTestDelete_Click(object sender, System.EventArgs e) { ds = new DataSet(); da.Fill(ds, "TestTable"); int i = ds.Tables[0].Rows.Count;//9 Debug.Write("Number of Rows Before 'Delete'" + i.ToString()); for(int x = 0; x < 5; x++)<BR> { ds.Tables[0].Rows[x].Delete(); } //Provet they are the same by Asserting i == Current Row Count Debug.Assert(i == ds.Tables[0].Rows.Count, "Counts Don't Match"); //Assertion Passes, proving Delete doesn't affect RowCount , Yet ds.Tables[0].AcceptChanges(); //After AcceptChanges - or da.Update, Deleted Rows are actually //deleted - Update calls AcceptChanges Debug.Assert(i ==ds.Tables[0].Rows.Count, "Counts Don't match"); //Fails now b/c AcceptChanges Removed the rows i = ds.Tables[0].Rows.Count;//Reset i ds.Tables[0].Rows.Remove(ds.Tables[0].Rows[0]); //Remove actually gets rid of the row, the assertion will fail //now Debug.Assert(i == ds.Tables[0].Rows.Count); } |