使用 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 中使用或避免使用 CommandBuilder