【发布时间】:2016-05-03 05:22:10
【问题描述】:
我有一个使用 SQLite DB 的 .net winforms 应用程序,我正在使用 System.Data.SQLite dll。
这是我加载数据表的方式:
DataTable table = new DataTable();
SQLiteDataAdapter m_readingsDataTableDataAdapter;
SQLiteCommandBuilder m_readingsDataTableCommandBuilder;
m_readingsDataTableCommandBuilder = null;
m_readingsDataTableDataAdapter = null;
// Create fresh objects
m_readingsDataTableDataAdapter = new SQLiteDataAdapter(sql, Database.getInstance().connectionObj);
m_readingsDataTableCommandBuilder = new SQLiteCommandBuilder(m_readingsDataTableDataAdapter);
m_readingsDataTableDataAdapter.Fill(table);
return table;
此数据表有一个主键,没有其他约束。 我将它设置为 DataGridView 的数据源,在所有编辑之后,我像这样更新 DataTable:
m_readingsDataTableDataAdapter.Update(table);
有时,更新会引发错误,我不知道何时会停止抛出错误 - 可能在系统重新启动后(不确定)。然后,更新正常,直到此更新再次引发错误的另一种情况。发生错误时,即使在应用程序重新启动后,从那时起的所有更新都会发生此错误。
错误: System.Data.dll 中出现“System.Data.DBConcurrencyException”类型的未处理异常 附加信息:并发冲突:UpdateCommand 影响了预期的 1 条记录中的 0 条。
如果有任何帮助或问题,我将不胜感激,因为这是我项目中非常关键的部分。
谢谢。
更新:
根据建议,为确保程序没有其他部分正在编辑该行,我加载了 DataTable,立即更新了该行并按照以下代码对其进行了更新。 我仍然得到错误。我的机器上没有运行其他程序,因此除了我的应用程序之外的任何其他程序都不会更新该行:
DataTable table = new DataTable();
SQLiteDataAdapter m_readingsDataTableDataAdapter;
SQLiteCommandBuilder m_readingsDataTableCommandBuilder;
m_readingsDataTableCommandBuilder = null;
m_readingsDataTableDataAdapter = null;
// Create fresh objects
m_readingsDataTableDataAdapter = new SQLiteDataAdapter(sql, Database.getInstance().connectionObj);
m_readingsDataTableCommandBuilder = new SQLiteCommandBuilder(m_readingsDataTableDataAdapter);
m_readingsDataTableDataAdapter.Fill(table);
// Update immediately
table.Rows[0]["RS485_ADDRESS"] = "400";
m_readingsDataTableDataAdapter.Update(table); // - Still throws error
return table;
【问题讨论】:
-
这意味着数据适配器和命令预期存在的行不再存在,或者它存在但它具有一些不同的关键值。货币违规源于这样一个事实,即当数据适配器最初检索数据时,它会制作两份副本,一份是底层副本,一份是公共副本。当您稍后尝试将更新保存回数据库时,它首先尝试验证该行是否仍在数据库中,并具有与最初相同的值。如果是,然后它执行更新。很明显,该行不存在或已更改。
-
意味着当您在一个地方操作该行时,其他一些代码或其他一些程序正在同时更新数据库中的同一行。当您稍后尝试更新它时,更新命令基本上说“将数据库中最初余额为 45 且最后到期日为今天的这一行更新为这个新余额”,并且该行在那里,但它不再余额为 45。
-
除了解释之外,我们无法帮助您,因为这需要您查看程序的大部分内容才能找出行意外更改的原因。如果您确实希望该行按照上述说明进行更改,那么您不能使用这种更新表的系统,因为这会导致问题。
-
非常感谢 Lasse 提供的信息丰富的回复。这真的很有帮助。我将对此进行进一步调查。
-
我对此进行了调查,根据我们拥有的代码,我确信该程序不会从其他“任何地方”更新“任何”行。实际上,我加载了一个表,连续更改了一个值并立即更新。它仍然抛出异常。请同时查看我的更新问题以及此信息和代码。
标签: c# sqlite concurrency sql-update