【问题标题】:Tricky bug with DataTable/Datasource autoincrement column syncing when deleting rows删除行时数据表/数据源自动增量列同步的棘手错误
【发布时间】:2012-01-17 03:41:13
【问题描述】:

我几天前发布了这个问题,但对这个问题做了一个正确的解释,所以希望这个尝试更清楚。在我的数据源(一个 MYSQL 数据库)上尝试使用 C# MySQLDataAdapter.Update() 函数时,我遇到了 DBConcurrency 错误。

我在 C# 程序中操作的 DataTable 的来源是我使用 MySQLDataAdapter 提取的数据库中的一个表。我想操作行,然后使用 DataAdapter 的 Update() 函数将更改保存到数据库。它在大多数情况下运行良好,但我发现了一个涉及自动递增列的难以解决的问题。

假设数据库表有一个记录列表,例如:

1 Apple
2 Orange
3 Banana
4 Pear

第一个 ID 列是自动递增的。我可以很好地填充 DataTable 并通过使用 MissingSchemaAction.AddWithKey() 等来自动递增,如果我向 DataTable 添加一条新记录“Grapes”,则自动递增 ID 列将为 5,当我使用它时数据库将接受它在其上运行 Update()。

但是,如果我将 Grapes 记录添加到 DataTable,然后将其删除,然后再次添加(我知道这不可信,但确实发生了),DataTable 自动增量只会不断增加,所以现在看起来像这样:

1 Apple
2 Orange
3 Banana
4 Pear
6 Grapes

如果我现在运行 Update(),“Grapes”记录自动 ID 将作为 5 保存到 DATABASE 表中,因为这是数据库自动增量所在的位置,但在 DataTable 中它被列为 6,所以它们现在重新不同步,如果我从 DataTable 中删除 Grapes 行并再次运行 Update(),我会收到错误消息:

"Concurrency violation: the DeleteCommand affected 0 of the expected 1 records."

在我的程序的 Update() 行上。

我环顾四周,似乎这种去同步可能相当频繁地发生,但在这个阶段,我想知道是否有什么我可以做的,而无需返回并撕毁我的大部分代码写过。

【问题讨论】:

  • 添加你自己的删除命令/过程并在里面放一个if存在,或者检测到你要删除的记录还没有发布,而是取消插入。
  • 问题不是我要删除的记录不存在,问题是我要删除的记录在DataTable,但数据库表中的 autoID 为 5,因此删除命令正在数据库中查找 autoID 6 并没有找到它(我认为?)
  • 你说你添加它然后删除它然后再次添加......除非你提交每个更改并刷新,独占锁定表,或者使用 GetChanges 和协调,这永远不会工作。插入记录的id不可能和底层sql表同步,断开了。

标签: c# mysql concurrency datatable dataadapter


【解决方案1】:

我能够解决此问题的唯一方法是执行以下操作:

DataTable copyTable = Table.Copy();
Table.Clear();

for( int i = 0; i < copyTable.Rows.Count; i++ )
 {
      DataRow r = copyTable.Rows[i];
      r[0] = i;
      Table.ImportRow( r );
 }

实际上,在我删除一行后,我将表复制到一个临时表,然后遍历剩余的行,使用行数设置我的“ID”列 (r[0])。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-15
    • 2014-06-24
    • 1970-01-01
    • 2014-08-10
    • 2015-03-18
    • 2014-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多