我正在尝试使用DataSet更新访问数据库。 DataSet读取xml,然后使用DataAdapter Update函数更新尝试更新数据库。
以下是代码
OleDbConnection connection = new OleDbConnection(this.ConnectionString);
connection.Open();
var adapter = new OleDbDataAdapter("SELECT TOP 1 * FROM Customer", connection);
adapter.ContinueUpdateOnError = true;
var dataSet = new DataSet();
dataSet.ReadXml("Update.xml");
OleDbCommandBuilder commandBuilder = new OleDbCommandBuilder(adapter);
foreach (DataRow row in dataSet.Tables[0].Rows)
{
row.AcceptChanges();
row.SetModified();
}
var result = adapter.Update(dataSet, "Customer");
这是xml
<NewDataSet>
<Customer>
<ID>1</ID>
<CustomerName>Customer 1</CustomerName>
</Customer>
<Customer>
<ID>2</ID>
<CustomerName>Customer 2</CustomerName>
</Customer>
</NewDataSet>
访问数据库中存在ID(1,2)。我想更新它们.. 更新函数返回2,这是更新的行数,但我没有看到访问数据库中的更新。 ID字段自动递增
但是,如果我运行以下
foreach (DataRow row in dataSet.Tables[0].Rows)
{
row["CustomerName"] = "Hi";
}
var result = adapter.Update(dataSet, "Customer");
然后在数据库中正确地重新更新更新。请帮助
答案 0 :(得分:0)
这是否使用属于项目一部分的访问数据库?获取访问数据库文件的属性 - 在项目构建时是否设置为“CopyAlways”?如果是这样,那么主项目目录中的访问数据库将被复制到每个构建的BIN目录中。您的应用可能会更新BIN中的数据库
您要么在项目中查找数据库并且没有找到任何更改(从来没有更新过的DB文件),或者您正在查看BIN文件夹中的数据库,但没有意识到每次构建完成,该文件被干净的副本覆盖 - &gt;看起来在连续运行应用程序之间没有保存更改
如果不是这种情况,我认为问题可能源于数据表中行的版本。使用.NET反编译器查看dataadapter.Update方法的代码,看看它是否正在以某种方式比较Row [由DataRowVersion索引] Original和Current值。
或许dataadapter构建的更新查询(使用调试器本地窗口来检查它)具有某种形式的乐观并发 - 这意味着它看起来像
UPDATE people SET name = @newName WHERE ID = @originalID and @name = @originalName
如果@originalname参数填充了一个新值(来自您的xml文件),而不是当前数据库表中的值,则查询将更新0条记录。乐观并发用于检测2个人对同一行的更改,逻辑基本上意味着如果DB中的行仍具有该oldValue,则只能将一行从oldValue更改为newValue。当我们正常使用数据库时,数据集知道什么是原始值 - 这是我们从数据库下载的内容。当您设置新值时,DataSet知道这是新值,但仍然记得旧值,以便它可以填充@oldName和@newName参数的(不同)值,并且除非有人在您之前更改了数据库,否则查询才会起作用设法
通常情况下,在使用错误的@oldValue的情况下,dataadapter将抛出ConcurrencyViolation“更新命令影响了1个预期行中的0”
我没有找到任何方法来关闭DbCommandBuilder文档中的乐观并发,你必须自己用另一个没有使用@oldValue的模式覆盖UPDATE语句
可能您最终会以稍微不同的方式处理问题:
将所有数据库数据下载到表中,将xml读入另一个数据集,循环访问数据集中数据集中的其他数据集更新值,dataadapter.update来自数据库的数据集
或者,更简单一点,从xml中读取数据集,循环执行更新命令直接到每行的数据库