注意:这是我之前提出的问题的简单版本。
我在同一个SQL Server数据库中有两个表,TestTable和TestTable2。没有主键。每个都有两列,
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命令非常笨重。
我在这段代码中是否遗漏了一些我没有看到的东西?如果是这样,它是什么?
感谢。
答案 0 :(得分:1)
在将数据更新到数据库之前尝试DataSet.AcceptChanges()。另外,检查DataSet.GetChanges()方法返回的内容。它不应该是一个空数据集。
最后,我在这里找到了解决方案:
答案 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);