使用 ADO.NET SqlDataAdapter 更新单个记录

Posted

技术标签:

【中文标题】使用 ADO.NET SqlDataAdapter 更新单个记录【英文标题】:Update Single Record with ADO.NET SqlDataAdapter 【发布时间】:2013-10-21 12:16:49 【问题描述】:

我正在使用 C# 在 Windows 窗体上使用 SqlDataAdapter。我有一个 BindingSource 将其链接到我的字段,并通过功能记录遍历并将更改保存回数据库。

我想让用户选择使用对当前记录的更改来更新数据库,而不是将所做的更改写入其他记录,而是将它们保存在缓存的修改集中(即保存与全部保存)。

我整理了以下可行的(有点):

SqlCommand updateCurrent = new SqlCommand("UPDATE Table SET Attribute = @attribute WHERE ID = @currentRecord", sqlConnection)

updateCurrent.Parameters.AddWithValue("@currentRecord", bindingSource.GetItemProperties(null)["ID"].GetValue(bindingSource.Current));
updateCurrent.Parameters.AddWithValue("@attribute", bindingSource.GetItemProperties(null)["Attribute"].GetValue(bindingSource.Current));

updateCurrent.ExecuteNonQuery();

它的工作原理是更新当前显示的记录(并且仅更新该记录),但是当稍后调用常规更新函数时,它会导致System.Data.DBConcurrencyException(UpdateCommand 影响了预期的 1 条记录中的 0 条)。

我想我明白为什么会发生错误(我对数据库进行了更改,但现在没有反映在缓存副本中),但不知道如何继续。

是否有执行此操作的最佳做​​法?从一开始就不是一个天生的坏主意吗?

【问题讨论】:

听起来你要使用DataTable 我实际上首先尝试过(使用DataViewRowState.ModifiedOriginal 从视图创建一个新的DataTable,按ID 删除当前记录的行,使用DataViewRowState.ModifiedCurrent 添加当前值,提交@ 987654328@ 到数据库,然后将BindingSource 链接表设置回原来的状态。我认为它似乎不必要地复杂(甚至比这更草率)。我想它会避免并发异常 - 我应该给它另一种方法是我刚才描述的方法? 【参考方案1】:

为了归档您想要的内容,您只需执行以下操作:

此命令将使用此特定行 (yourDataRow) 的内容更新您的数据库。

YourTableAdapter.Update(yourDataRow);

此命令将更新整个 DataTable。

YourTableAdapter.Update(yourDataTable);

DataTable 会知道哪一行被更新,哪一行被保存。

【讨论】:

谢谢 - 非常简单,但正是我希望实现的!这是我用来为希望完成类似任务的任何人获取当前记录的 DataRow 的行:DataRow[] activeRecord = dataTable.Select("ID = " + bindingSource.GetItemProperties(null)["ID"].GetValue(bindingSource.Current), null, DataRowViewState.ModifiedCurrent);【参考方案2】:

看一看之后就在这里吐个球。但是:

问题 #1 我会这样做:如果您在更新发生时保存更新,那么“全部保存”的想法几乎被抛在了窗外(没用),因为当一切都已经是最新的时,保存所有显然是低效的. ...因此,一次更新一个或要求全部保存。

问题 #2(实际抱怨的问题) DBConcurrencyException 不是错误,它是抛出的异常(差异),抛出它的唯一原因是没有对数据库进行更新。 (因为您已经在逐行保存)因此为什么要更新?你不会的。所以也许一个空的 try/catch 将是最好的路线,因为你似乎是自动保存的。

我会做的方式(老实说): 除非您正在处理大量数据(假设 > 10,000 行),否则我会创建一个“全部保存”函数来更新所有已更改的行(也许使用焦点侦听器并将其添加到列表或其他内容中)出零钱)。如果您想在每次进行编辑时都保存,请使用“全部保存”功能,在这种情况下,它只是 1 行。如果其他人被更改,请全部保存以进行救援。各方面工作。

附加奖励:使用缓存副本实际上是一个愚蠢的想法。 (除非您的计算机是野兽)就像我对小数据所说的那样,完全可以。但是让我们想象一个 1,000,000 行的数据库。现在尝试缓存 1,000,000 行......不,你是对的,比较会更快,但是将所有不需要的数据加载到内存中是一个可怕的想法。缩放时您的程序会崩溃。

【讨论】:

以上是关于使用 ADO.NET SqlDataAdapter 更新单个记录的主要内容,如果未能解决你的问题,请参考以下文章

使用 ADO.NET 的批处理操作

在 ADO.NET 中使用或避免使用 CommandBuilder

ADO.NET常用五种对象

ADO.NET之使用DataSet类更新数据库

如何用DataSet 和SqlDataAdapter读取SQL数据库中某列的多行数据?

如何将自定义子查询传递给 ADO.NET 中的 SQL 命令?