0

我有以下代码应该用远程用户表覆盖本地用户表。我可以看到 Merge 工作正常,但 Update 什么也不做(即 DataTable 有新值,但它没有将其写入 LocalDb 连接/数据库) - 有没有一种简单的方法来做我正在做的事情或做这个工作?

var RemoteUsersTable = DbRemote.ExecuteQuery("SELECT * FROM users");

if (RemoteUsersTable.Rows.Count > 0)
{
    SqlDataAdapter LocalDataAdapter = null;
    var LocalUsersTable = DbLocal.ExecuteQuery("SELECT * FROM users", ref LocalDataAdapter);

    LocalUsersTable.Merge(RemoteUsersTable);
    LocalUsersTable.AcceptChanges();

    LocalDataAdapter.Update(LocalUsersTable);
}
4

2 回答 2

0

对 AcceptChanges 的调用意味着 LocalUsersTable 中的任何更改值都不再标记为已更改,因此无需更新任何内容。

无论如何,这是执行大规模更新的一种非常丑陋、缓慢且有风险的方式,并且从未使用过。只是一些最严重的问题:

  • 您将所有数据从两台服务器拉到客户端,然后再将所有数据发送回其中一台服务器。这浪费了所有机器的带宽和处理时间,因此非常慢。
  • 您从每个表中检索所有列,如果有架构更改,这将导致更新失败。

您应该在事务中使用 SQL 语句来做您想做的事情,而不是使用 DataTables。

SQL Server 有 MERGE 语句,它可以使用源查询中的行更新目标表,使用每个单独行的值决定做什么(更新、插入、删除)。或者您可以编写一个多语句脚本,删除旧行并将新行插入事务中

于 2012-12-03T11:15:13.027 回答
0

上面代码的问题是你只设置了一个选择命令。如果您想“更新”表格,那么您很可能需要为您的LocaDataAdapter.

DataAdapter的Update方法需要这些命令来更改/添加/删除数据库表中的记录。

您通常会使用特定命令设置 DataAdapter。

使用您的命令生成器,您可以尝试这样做:-

var RemoteUsersTable = DbRemote.ExecuteQuery("SELECT * FROM users");

if (RemoteUsersTable.Rows.Count > 0)
{
    SqlDataAdapter LocalDataAdapter = null;
    var LocalUsersTable = DbLocal.ExecuteQuery("SELECT * FROM users", ref LocalDataAdapter);

    LocalUsersTable.Merge(RemoteUsersTable);
    LocalUsersTable.AcceptChanges();

    cb.GetDeleteCommand(); // WHICH EVER YOUR COMMANDBUILDER IS CALLED.
    cb.GetInsertCommand();
    cb.GetUpdateCommand();

    LocalDataAdapter.Update(LocalUsersTable);
}
于 2012-12-03T11:11:45.357 回答