![](/img/trans.png)
[英]Inserting Data into multiple SQL tables with foreign key constraints using C#
[英]Adding data in multiple tables in one shot with a foreign key constraints between them
我想在一個事務中對不同表進行插入操作時遇到問題。 這樣,如果事務失敗,則表中的任何數據都不會受到不一致的數據的污染。
這個問題還有另一個約束。 表2與表1的主鍵(auto_increment)具有外鍵關系。 因此,當我在表1和表2中添加新條目時,我需要在新表2條目中添加表1的新主鍵,這是同一事務的一部分。
我正在使用MYSQLDataAdaptor填充SB。
問題陳述有些棘手,如果需要進一步說明,請告訴我。
提前致謝 !!
我已經使用交易概念解決了這個問題。
MySqlDataAdapter [] all_adapters = new MySqlDataAdapter[2];
DataTable [] data_tables = new DataTable[2];
for (int i = 0; i < 2; i++ )
{
all_adapters[i] = new MySqlDataAdapter(query[i], connection);
MySqlCommandBuilder cb = new MySqlCommandBuilder(all_adapters[i]);
all_adapters[i].InsertCommand = cb.GetInsertCommand();
data_tables[i] = new DataTable();
all_adapters[i].Fill(data_tables[i]);
}
MySqlTransaction transaction = connection.BeginTransaction();
try
{
for (int i = 0; i < 2; i++ )
{
all_adapters[i].InsertCommand.Transaction = transaction;
if (i == 0)
{
... Add entry in table-1
// Fetch new auto_increment primary key of table-1
string new_query = "SELECT LAST_INSERT_ID();";
MySqlCommand cmd = new MySqlCommand(new_query, connection);
int primary_id_table1 = Convert.ToInt32(cmd.ExecuteScalar());
}
else
{
... Add entry in table-2.
Use primary_id_table1 to populate the foreign key in table-2
}
}
transaction.Commit();
}
catch (Exception e)
{
transaction.Rollback();
}
這將確保在事務影響回滾時,兩個表都同時在數據庫中更新,或者沒有一個表被更新。 這將有助於維持數據庫的一致性。 因此,在給定事務中保持ACID屬性。
我認為,只有跟蹤表1主鍵並使用預先計算的主鍵生成插入內容,才有可能。 因此,您必須確定,沒有人不能在同一表中同時插入任何數據。
我摸了一下頭,直到我終於意識到這個問題。 我試圖用自動遞增的ID字段更新兩個主表,然后使用前兩個表中記錄的ID值更新第三個表,所有這些都在事務內。 我發現數據集中的AutoIncrement主鍵字段將不是更新后寫入記錄的實際值(它們的字段將具有值,但不一定是正確的值)。 當讀取表模式時,它將只是種子值序列中的下一個對象。 因此,要處理此問題,請將RowUpdated處理程序添加到您的DataAdapter並讀取command.LastInsertedId屬性。 這樣,AutoIncrement值就是表中寫入的實際值。 然后將新記錄添加到第三個表中。
{
MySqlDataAdapter daAll = new MySqlDataAdapter("Select * from courses;Select * from productsku;Select * from productcourseassociation;", sqlConn);
MySqlDataAdapter daCourses = new MySqlDataAdapter("Select * from courses;", sqlConn);
MySqlDataAdapter daSku = new MySqlDataAdapter("Select * from productsku;", sqlConn);
MySqlDataAdapter daAssoc = new MySqlDataAdapter("Select * from productcourseassociation;", sqlConn);
daCourses.RowUpdated += DaCourses_RowUpdated;
daSku.RowUpdated += DaSku_RowUpdated;
DataSet ds = new DataSet();
daAll.FillSchema(ds, SchemaType.Source);
daCourses.TableMappings.Add("courses", "Table");
daSku.TableMappings.Add("productsku", "Table1");
daAssoc.TableMappings.Add("productcourseassociation", "Table2");
ForeignKeyConstraint fkConstraint1 = new ForeignKeyConstraint("fk1", ds.Tables[0].Columns["courseid"], ds.Tables[2].Columns["courseid"]);
ForeignKeyConstraint fkConstraint2 = new ForeignKeyConstraint("fk2", ds.Tables[1].Columns["skuid"], ds.Tables[2].Columns["skuid"]);
ds.Tables[2].Constraints.Add(fkConstraint1);
ds.Tables[2].Constraints.Add(fkConstraint2);
MySqlCommandBuilder cbCourses = new MySqlCommandBuilder(daCourses);
MySqlCommandBuilder cbSku = new MySqlCommandBuilder(daSku);
MySqlCommandBuilder cbAssoc = new MySqlCommandBuilder(daAssoc);
DataRow courseRow = ds.Tables[0].NewRow();
courseRow["coursename"] = courseName;
ds.Tables[0].Rows.Add(courseRow);
r = ds.Tables[1].NewRow();
r["skudesc"] = courseName;
r["duration"] = 1;
ds.Tables[1].Rows.Add(r);
r = ds.Tables[1].NewRow();
r["skudesc"] = courseName;
r["duration"] = 3;
ds.Tables[1].Rows.Add(r);
r = ds.Tables[1].NewRow();
r["skudesc"] = courseName;
r["duration"] = 12;
ds.Tables[1].Rows.Add(r);
daCourses.Update(ds, "Table");
daSku.Update(ds, "Table1");
daAssoc.Fill(ds, "Table2");
int courseId = Convert.ToInt32(courseRow["courseid"]);
DataRow[] skurows = ds.Tables[1].Select(String.Format("skudesc='{0}'", courseName));
foreach (DataRow dr in skurows)
{
r = ds.Tables[2].NewRow();
r["skuid"] = dr["skuid"];
r["courseid"] = courseId;
ds.Tables[2].Rows.Add(r);
}
daAssoc.Update(ds, "Table2");
}
private void DaSku_RowUpdated(object sender, MySqlRowUpdatedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Row updated");
e.Row["skuid"] = e.Command.LastInsertedId;
}
private void DaCourses_RowUpdated(object sender, MySqlRowUpdatedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Row updated");
e.Row["courseid"] = e.Command.LastInsertedId;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.