簡體   English   中英

一鍵添加多個表中的數據,並且它們之間具有外鍵約束

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM