使用XML文件中的数据集datadapter更新任何数据源

时间:2017-07-26 18:14:31

标签: xml ado.net dataset dataadapter

我正在尝试使用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");

然后在数据库中正确地重新更新更新。请帮助

1 个答案:

答案 0 :(得分:0)

这是否使用属于项目一部分的访问数据库?获取访问数据库文件的属性 - 在项目构建时是否设置为“CopyAlways”?如果是这样,那么主项目目录中的访问数据库将被复制到每个构建的BIN目录中。您的应用可能会更新BIN中的数据库

您要么在项目中查找数据库并且没有找到任何更改(从来没有更新过的DB文件),或者您正在查看BIN文件夹中的数据库,但没有意识到每次构建完成,该文件被干净的副本覆盖 - &gt;看起来在连续运行应用程序之间没有保存更改

http://www.vbdotnetforums.com/showthread.php/18096-FAQ-quot-My-database-isnt-saving-changes-quot-or-quot-Changes-are-gone-when-I-restart-the-app-quot?p=54914#post54914

如果不是这种情况,我认为问题可能源于数据表中行的版本。使用.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中读取数据集,循环执行更新命令直接到每行的数据库