【问题标题】:SqlDataAdapter.Update - PART 2SqlDataAdapter.Update - 第 2 部分
【发布时间】:2011-07-07 22:10:12
【问题描述】:

注意:这是我之前应该写的问题的简单版本。

我在同一个 SQL Server 数据库中有两个表,TestTable 和 TestTable2。两者都没有主键。每个都有两列,

  1. TestInt (int)
  2. TestString (varchar(50))

TestTable2中有数据,而TestTable为空。我想通过 C# 将一个的内容复制到另一个。 (我知道这可以在 SQL 中完成,但在这里请幽默。)

这是我为完成这项工作而编写的代码,使用 SqlDataAdapter 对象...

// Data in TestTable2, nothing in TestTable.
private static void Main(string[] args)
{
    SqlConnection conn = /* CONNECTION CREATION CODE */
    string sqlQuery = "SELECT * FROM TestTable2";
    DataTable payload = /* SIMPLE QUERY CODE USING sqlQuery */

    // CODE CHECKPOINT #1

    sqlQuery = "SELECT * FROM TestTable";
    SqlCommand sCmd = new SqlCommand(sqlQuery, conn);
    SqlDataAdapter sDA = new SqlDataAdapter(sCmd);     
    DataSet dataSet = new DataSet();     
    conn.Open();     
    sDA.Fill(dataSet);     
    conn.Close();

    for (int i = 0; i < payload.Rows.Count; i++)
    {
        dataSet.Tables[0].ImportRow(payload.Rows[i]);
    }

    // CODE CHECKPOINT #2

    SqlCommandBuilder cb = new SqlCommandBuilder(sDA); 

    conn.Open();     
    sDA.Update(dataSet);     
    conn.Close();
}

问题是这段代码不起作用。如果我要在检查点 #1 检查 DataTable 'payload' 的内容,我会看到 4 行,而 dataSet.Tables[0] 中有 0 行。如果我随后在检查点 #2 检查“dataSet”的内容,我在 dataSet.Tables[0] 中看到 4 行! 但是,在程序结束时,TestTable2 中的所有行都没有进入TestTable。

换句话说,C# 在 DataTable 之间移动数据,但对表本身没有影响。

我发现添加新创建的行

DataRow row = DataSet.DataTable.NewRow(...);
...
dataSet.Tables[i].Rows.Add(row);

到目标 DataSet 与 SqlDataAdapter.Update 一起使用,但在这种情况下不合适,因为您不能在单独的 DataTable 保存的行上使用 DataTable.Rows.Add。因此,我的问题是,因为这使我无法将数据从一个表传输到另一个表,尤其是在涉及大量列的情况下,这会导致显式 SQL 命令非常笨拙。

此代码中是否缺少我没有看到的内容?如果有,是什么?

谢谢。

【问题讨论】:

    标签: c# .net sql-server


    【解决方案1】:

    在将数据更新到数据库之前尝试 DataSet.AcceptChanges()。此外,请检查 DataSet.GetChanges() 方法返回的内容。它不应该是一个空的 DataSet。

    最后,我在这里找到了解决方案:

    importrow --> update fails

    【讨论】:

      【解决方案2】:

      最终答案是 platon 提供的链接的翻译。但是,我在此处包含显式代码以方便将来参考。

      基本上,ImportRow 并不总是为添加的行设置脏位。因此,SqlDataAdapter.Update 不一定会将更改移动到 SQL,因为它不会将新行识别为更改的数据。为确保设置了脏位,您需要调用 DataTable.Rows.Add,但如前所述,这不能使用另一个表的行作为参数来调用。

      怎么办?不要将该行用作 Add() 的参数。相反,使用 object[] ItemArray...

      for(int i = 0 ; i < srcTable.Rows.Count ; i++)
      {
          destTable.Rows.Add(srcTable.Rows[i].ItemArray);
      }
      ...
      SqlCommandBuilder sCB = new SqlCommandBuilder(adapter);
      adapter.Update(dataSet);
      

      【讨论】:

        猜你喜欢
        • 2014-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-01
        • 2011-09-08
        • 2011-01-02
        • 1970-01-01
        相关资源
        最近更新 更多