2010-05-14 51 views
0

我可以得到這個工作,但我覺得好像我沒有做得很好。CommandBuilder和SqlTransaction插入/更新一行

這第一次運行時,它按預期工作,一個新的行插入其中,「thisField」包含「doesntExist」

但是,如果我運行它在隨後的時間,我得到一個運行時錯誤我無法插入重複密鑰,因爲它違反了主鍵「thisField」。


static void Main(string[] args) 
{   
    using(var sqlConn = new SqlConnection(connString)) 
    { 
     sqlConn.Open(); 
     var dt = new DataTable(); 

     var sqlda = new SqlDataAdapter("SELECT * FROM table WHERE thisField ='doesntExist'", sqlConn); 
     sqlda.Fill(dt); 

     DataRow dr = dt.NewRow(); 

     dr["thisField"] = "doesntExist"; //Primary key 

     dt.Rows.Add(dr); 

     //dt.AcceptChanges(); //I thought this may fix the problem. It didn't. 

     var sqlTrans = sqlConn.BeginTransaction(); 

     try 
     { 
      sqlda.SelectCommand = new SqlCommand("SELECT * FROM table WITH (HOLDLOCK, ROWLOCK) WHERE thisField = 'doesntExist'", sqlConn, sqlTrans); 

      SqlCommandBuilder sqlCb = new SqlCommandBuilder(sqlda); 

      sqlda.InsertCommand = sqlCb.GetInsertCommand(); 
      sqlda.InsertCommand.Transaction = sqlTrans; 

      sqlda.DeleteCommand = sqlCb.GetDeleteCommand(); 
      sqlda.DeleteCommand.Transaction = sqlTrans; 

      sqlda.UpdateCommand = sqlCb.GetUpdateCommand(); 
      sqlda.UpdateCommand.Transaction = sqlTrans; 

      sqlda.Update(dt); 

      sqlTrans.Commit(); 
     } 
     catch (Exception) 
     { 
      //... 
     } 
    } 
}

即使我可以通過走動的AcceptChanges,或在封裝變化的試驗和錯誤的工作開始/ EndEdit中,然後我開始體驗「併發衝突」中,它不會更新改變,而是告訴我它無法更新1個受影響的行中的0個。

有什麼瘋狂的明顯我失蹤?

回答

1

我能夠通過在填寫數據表後手動刪除行來解決我的問題。我無法使用dt.Clear(),因爲這樣做仍然會導致出現異常,因爲嘗試插入帶有重複主鍵的記錄。


sqladapter.Fill(dt); 

foreach(DataRow d in dt.Rows) 
    d.Delete(); 

DataRow dr = dt.NewRow(); 

dr.BeginEdit(); 
//update dr 
dr.EndEdit(); 

dt.Rows.Add(dr);

以上將成功讓我插入一個新行,並更新一個預先存在的行。刪除foreach將生成「不能在對象中插入重複鍵」,所以我覺得我至少已經找到了a解決方案;雖然,我覺得它不是解決方案。

希望這可以幫助別人。