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 的尝试和错误,或者在 Begin/EndEdit 中封装更改,然后我开始遇到“并发冲突”,它不会更新更改,而是告诉我它失败了更新 1 个受影响行中的 0 个。
我错过了什么明显的疯狂的东西吗?
I can get this to work, but I feel as though I'm not doing it properly.
The first time this runs, it works as intended, and a new row is inserted where "thisField" contains "doesntExist"
However, if I run it a subsequent time, I get a run-time error that I can't insert a duplicate key as it violate the primary key "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)
{
//...
}
}
}
Even when I can get that working through trial and error of moving AcceptChanges around, or encapsulating changes within Begin/EndEdit, then I begin to experience a "Concurrency violation" in which it won't update the changes, but rather tell me it failed to update 0 of 1 affected rows.
Is there something crazy obvious I'm missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我能够通过在填充数据表后手动删除行来解决我的问题。我无法使用 dt.Clear() ,因为这样做仍然会由于尝试插入具有重复主键的记录而导致异常。
上面的代码将成功地让我插入一个新行,并更新一个预先存在的行。删除 foreach 将生成“无法在对象中插入重复的键”,所以我觉得我至少找到了一个解决方案;虽然,我觉得这不是的解决方案。
希望这对某人有帮助。
I was able to over come my problems by manually deleting the row(s) after filling the datatable. I'm unable to use
dt.Clear()
, as doing so still results in an exception due to trying to insert a record with a duplicate primary key.The above will successfully let me insert a new row, and update a pre-existing row. Removing the foreach will generate the "Cannot insert duplicate key in object," so I feel I've at least found a solution; although, I feel as though it's not the solution.
Hope this helps someone.