SqlDataAdapter.Update - 第2部分

时间:2011-07-07 22:10:12

标签: c# .net sql-server

注意:这是我之前提出的问题的简单版本。

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

  1. TestInt(int)
  2. TestString(varchar(50))
  3. 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();
    }
    

    问题是此代码无效。如果我在Checkpoint#1检查DataTable'payload'的内容,我会看到4行,而dataSet.Tables [0]中有0行。如果我然后在Checkpoint#2检查'dataSet'的内容,我在dataSet.Tables [0]中看到4行!但是,在程序结束时,TestTable2的所有行都没有把它变成了TestTable。

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

    我发现添加新创建的行

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

    进入目标DataSet与SqlDataAdapter.Update一起使用,但在这种情况下这不合适,因为您不能在由单独的DataTable持有的行上使用DataTable.Rows.Add。因此,我的问题,因为这使我无法将数据从一个表传输到另一个表,特别是在涉及大量列的情况下,呈现显式SQL命令非常笨重。

    我在这段代码中是否遗漏了一些我没有看到的东西?如果是这样,它是什么?

    感谢。

2 个答案:

答案 0 :(得分:1)

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

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

importrow --> update fails

答案 1 :(得分:0)

最终答案是由柏拉图提供的链接的翻译。但是,我在这里包含了显式代码,以便日后参考。

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

怎么办?不要将该行用作Add()的参数。相反,使用对象[] 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);