在我的应用程序中,我有一个控件,向用户显示数据库表的内容。此控件保存要在System.Data.DataSet
对象中显示的数据。用户可以修改控件中显示的数据,然后在用户完成后将这些数据提交回数据库。
当用户在控件中进行编辑时,某些外部进程(例如某些行已更新)修改了数据库表中的数据时出现问题。暂时忽略数据正确性的问题,我想要做的是提交用户在控件中所做的更改并覆盖此外部进程所做的更改。
我正在使用SqlDataAdapter
来更新数据库。在所描述的用例中,当外部进程未修改基础数据库表时,SqlDataAdapter.Update
按预期工作。但是,在用户编辑它时某些外部进程在表中摆弄的情况下,SqlDataAdapter.Update
不会抛出异常但返回0表示没有更新行。我已经检查过我的数据集中的行是否有正确的数据和RowState
(即DataRowState.Modified
)所以我知道我传入SqlDataAdapter.Update
方法的数据是正确的。
我想我的问题有两部分。
SqlDataAdapter.Update
没有使用指定的数据集更新数据库?我已阅读this blog entry,而我的代码并未在任何地方调用AcceptChanges
,正如我上面所述,我已检查了DataSet
的{{1}}所以我知道行被正确标记为已修改数据。
答案 0 :(得分:1)
您的表的结构是什么以及您使用的版本控制机制(时间戳,日期时间等)是什么?有很多事情可以影响SqlDataAdapter
最终处理版本控制的方式,但我的猜测是你在表上有一个时间戳,或者有SqlCommandBuilder
生成{{3} (通过SqlCommand
方法)最终检查数据库中行中的所有值与您更新的行中的先前值(GetUpdateCommand
存储行的先前版本以进行比较)。
所有这些都起到了作用,因为ADO.NET将为您尝试并维护DataRow
;如果其他人自上次提取记录以来修改了记录,则不会进行更新。
这显然不是你想要的行为;你想要一个最后的方法。
为此,在SqlDataAdapter
上将optimistic concurrency属性显式设置为SqlCommand
,它将执行更新而不检查时间戳,它只更新主键所在的记录等于您指定的DataRow
中的值(或列中具有唯一约束的值)。