How to update multiple tables to database???

Jan 16 2005 2:54 AM
I create 2 tables, ParentTable and ChildTable. The row in ChildTable is referenced to ParentTable. But after updated and saved to database, the row in ChildTable doesn't refer to the correct row in ParentTable. You can see the following example to get the problems. Is there any good way to update multiple tables by using SqlDataAdapter.Update()? Thank you /* New Rows in ParentTable and ChildTable * * ------ParentTable------ * ID Animal * 1 Cat * * * ------ChildTable------ * ID NAME ParentID * "1 small cat 1" */ /* * But after the new rows saved back to the database, the new rows saved wrongly as: * * ------ChildTable------ * ID NAME ParentID * 1 small bird 1 * 2 small dog 2 * 3 small cat 1 =====> The ParentID doesn't dynamically change to 3 but keep the same as 1. * This makes it doen't reference to the correct row in ParentTable */ ------------------------------------------------------------------------------------ I try to use 2 different ways to update tables. But they both result in the same problem. The first way I use is to follow the update sequence recommended by book: adapter1= new SqlDataAdapter("Select * from ChildTable", con); SqlDataAdapter adapter2= new SqlDataAdapter("Select * from ParentTable", con); SqlCommandBuilder sb = new SqlCommandBuilder(adapter1); SqlCommandBuilder sb1 = new SqlCommandBuilder(adapter2); adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null, DataViewRowState.Deleted)); adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null, null, DataViewRowState.Deleted)); adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null, null, DataViewRowState.ModifiedCurrent)); adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null, null, DataViewRowState.Added)); adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null, DataViewRowState.ModifiedCurrent)); adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null, DataViewRowState.Added)); ------------------------------------------------------------------------------------- The 2nd way is to use 2 SqlDataAdapter seperately to update tables, but still get the same problem : The Child table row "3 small cat 1" is wrong adapter1= new SqlDataAdapter("Select * from ChildTable", con); SqlDataAdapter adapter2= new SqlDataAdapter("Select * from ParentTable", con); SqlCommandBuilder sb = new SqlCommandBuilder(adapter1); SqlCommandBuilder sb1 = new SqlCommandBuilder(adapter2); adapter1.Update(NewDataSet.Tables["ChildTable"]); adapter2.Update(NewDataSet.Tables["ParentTable"]); Please refer to the UpdateTableMethod1() and UpdateTableMethod2() in the codes I provide. ------------------------------------------------------------------------------------ I just put some codes on the website. If you are also interested, you can just copy-paste the code on your file and run it. This code would generate 2 tables and insert content to the tables in NorthWindCs database in MsSql server. Please change the connection string to yours. using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Data.SqlClient; namespace UpdateMultipleTables { /// /// Summary description for Form1. /// public class Form1 : System.Windows.Forms.Form { /// /// Required designer variable. /// private System.ComponentModel.Container components = null; private System.Windows.Forms.DataGrid dataGrid1; //private conStr = "Server=Local; SSPT = true; "; private string conStr = "server=Local;User ID=sa; PWD=hello;database=NorthWindCs"; SqlDataAdapter adapter1 ; SqlConnection con ; private DataSet NewDataSet; public Form1() { InitializeComponent(); //Create the connection to DataBase CreateConnection(); //Create tables "ParentTable" and "ChildTable". And Insert content to the 2 tables CreateDB(); //Create a new row in both ParentTable and ChildTable CreateNewRow(); //I try 2 ways to update the tables. But both of them gave me the same problem, //The new row in "ChildTable": is WRONG! //UpdateTable1Method1(); UpdateTableMethod2(); } public void CreateConnection() { con = new SqlConnection(conStr); } //Create tables "ParentTable" and "ChildTable". And Insert content to the 2 tables public void CreateDB() { string commandText = "if exists (select * from NorthwindCS.dbo.sysobjects where name like 'ParentTable') "+ "Begin " + "DROP TABLE ParentTable "+ "CREATE TABLE ParentTable( ID INT IDENTITY(1,1) NOT NULL , Animal VARCHAR(40) NOT NULL ) "+ "INSERT INTO ParentTable( Animal) values('Bird') "+ "INSERT INTO ParentTable( Animal) values('Dog') "+ "END "+ "ELSE "+ "Begin "+ "CREATE TABLE ParentTable( ID INT IDENTITY(1,1) NOT NULL , Animal VARCHAR(40) NOT NULL ) "+ "INSERT INTO ParentTable( Animal) values('Bird') "+ "INSERT INTO ParentTable( Animal) values('Dog') "+ "END "+ "IF exists (select * from NorthwindCS.dbo.sysobjects where name like 'ChildTable') "+ "Begin "+ "DROP table ChildTable "+ "CREATE TABLE ChildTable( ID INT IDENTITY(1,1) NOT NULL , Name VARCHAR(40) NOT NULL , ParentID INT Not NULL) "+ "INSERT INTO ChildTable( Name, ParentID) values('small bird', 1) "+ "INSERT INTO ChildTable( Name ,ParentID) values('small dog', 2) "+ "END "+ "ELSE "+ "BEGIN "+ "CREATE TABLE ChildTable( ID INT IDENTITY(1,1) NOT NULL , Name VARCHAR(40) NOT NULL , ParentID INT Not NULL) "+ "INSERT INTO ChildTable( Name, ParentID) values('small bird', 1) "+ "INSERT INTO ChildTable( Name ,ParentID) values('small dog', 2) "+ "END "; adapter1 = new SqlDataAdapter(commandText, con); try { DataSet ds = new DataSet(); adapter1.Fill(ds); dataGrid1.DataSource = ds; } catch(Exception e) { Console.WriteLine(e.Message); } } /* New Rows in ParentTable and ChildTable * * ------ParentTable------ * ID Animal * 1 Cat * * * ------ChildTable------ * ID NAME ParentID * "1 small cat 1" */ /* * But after the new rows saved back to the database, the new rows saved wrongly as: * * ------ChildTable------ * ID NAME ParentID * 1 small bird 1 * 2 small dog 2 * 3 small cat 1 =====> The ParentID doesn't dynamically change to 3 but keep the same as 1. * This makes it doen't reference to the correct row in ParentTable */ //Create a new row in both ParentTable and ChildTable public void CreateNewRow() { //carete data in parent table NewDataSet = new DataSet("NewDataSet"); DataTable ParentTable = new DataTable("ParentTable"); DataColumn dc = new DataColumn("ID", typeof(int)); dc.AutoIncrement = true; dc.AutoIncrementSeed = 1; dc.AutoIncrementStep = 1; ParentTable.Columns.Add(dc); dc = new DataColumn("Animal", typeof(string)); ParentTable.Columns.Add(dc); NewDataSet.Tables.Add(ParentTable); DataTable ChildTable = new DataTable("ChildTable"); dc = new DataColumn("ID", typeof(int)); dc.AutoIncrement = true; dc.AutoIncrementSeed = 1; dc.AutoIncrementStep = 1; ChildTable.Columns.Add(dc); dc = new DataColumn("Name", typeof(string)); ChildTable.Columns.Add(dc); dc = new DataColumn("ParentID", typeof(int)); ChildTable.Columns.Add(dc); NewDataSet.Tables.Add(ChildTable); // DataRelation relation = new DataRelation("ParentChildRelation" , ParentTable.Columns["ID"], ChildTable.Columns["ParentID"], true); // NewDataSet.Relations.Add(relation); DataRow dr = NewDataSet.Tables["ParentTable"].NewRow(); dr["Animal"] = "Cat"; NewDataSet.Tables["ParentTable"].Rows.Add(dr); //carete data in child table dr = NewDataSet.Tables["ChildTable"].NewRow(); dr["Name"] = "small cat"; dr["ParentID"] = NewDataSet.Tables["ParentTable"].Rows[0]["ID"]; NewDataSet.Tables["ChildTable"].Rows.Add(dr); dataGrid1.DataSource = NewDataSet; } //This update method followed by the recommended sequence of updateing tables in Oreilly book. But it doesn't solve //my proble. The Child table row "3 small cat 1" is wrong public void UpdateTableMethod1() { try { adapter1= new SqlDataAdapter("Select * from ChildTable", con); SqlDataAdapter adapter2= new SqlDataAdapter("Select * from ParentTable", con); SqlCommandBuilder sb = new SqlCommandBuilder(adapter1); SqlCommandBuilder sb1 = new SqlCommandBuilder(adapter2); adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null, DataViewRowState.Deleted)); adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null, null, DataViewRowState.Deleted)); adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null, null, DataViewRowState.ModifiedCurrent)); adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null, null, DataViewRowState.Added)); adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null, DataViewRowState.ModifiedCurrent)); adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null, DataViewRowState.Added)); } catch(Exception e) { Console.WriteLine(e.Message); } } //I try to use 2 SqlDataAdapter to update tables, but still get the same problem : The Child table row "3 small cat 1" is wrong public void UpdateTableMethod2() { try { adapter1= new SqlDataAdapter("Select * from ChildTable", con); SqlDataAdapter adapter2= new SqlDataAdapter("Select * from ParentTable", con); SqlCommandBuilder sb = new SqlCommandBuilder(adapter1); SqlCommandBuilder sb1 = new SqlCommandBuilder(adapter2); adapter1.Update(NewDataSet.Tables["ChildTable"]); adapter2.Update(NewDataSet.Tables["ParentTable"]); } catch(Exception e) { Console.WriteLine(e.Message); } } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.dataGrid1 = new System.Windows.Forms.DataGrid(); ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit(); this.SuspendLayout(); // // dataGrid1 // this.dataGrid1.DataMember = ""; this.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText; this.dataGrid1.Location = new System.Drawing.Point(16, 24); this.dataGrid1.Name = "dataGrid1"; this.dataGrid1.Size = new System.Drawing.Size(496, 216); this.dataGrid1.TabIndex = 0; // // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(560, 294); this.Controls.Add(this.dataGrid1); this.Name = "Form1"; this.Text = "Form1"; ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit(); this.ResumeLayout(false); } #endregion /// /// The main entry point for the application. /// [STAThread] static void Main() { Application.Run(new Form1()); } } }