简体   繁体   中英

SqlDataAdapter.Update - PART 2

NOTE: This is the simple version of my previous question that SHOULD have been written.

I have two tables in the same SQL Server database, TestTable and TestTable2. Neither has a primary key. Each have two columns,

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

There is data in TestTable2, while TestTable is empty. I want to copy the contents of one into the other, via C#. (I know this can be done in SQL, but humor me here.)

Here is the code I've written to do the job, using a SqlDataAdapter object...

// 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();
}

The problem is that this code is not working. If I were to check the contents of DataTable 'payload' at Checkpoint #1, I see 4 rows, while there are 0 rows in dataSet.Tables[0]. If I then check the contents of 'dataSet' at Checkpoint #2, I see 4 rows in dataSet.Tables[0]! However, at the end of the program, none of the rows from TestTable2 have made it into TestTable.

In other words, C# is moving the data between the DataTables, but it is having no affect on the tables themselves.

I've found that adding newly created rows

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

into the destination DataSet works with SqlDataAdapter.Update, but that's not appropriate in this case, as you cannot use DataTable.Rows.Add on a row held by a separate DataTable. Hence, my problem, as this has rendered me incapable of transfering data from one table to another, especially in cases where large numbers of column are involved, rendering explicit SQL commands very clunky.

Is there something I'm missing in this code that I'm not seeing? If so, what is it?

Thanks.

Try DataSet.AcceptChanges() before updating data to the DB. Also, check, what the DataSet.GetChanges() method returns. It should not be an empty DataSet.

Finally, I have found the solution here:

importrow --> update fails

The ultimate answer is a translation of the link provided by platon. However, I'm including the explicit code here for easier future reference.

Basically, ImportRow doesn't always set the dirty bit for the added rows. As a result, SqlDataAdapter.Update won't necessarily move the changes to SQL since it doesn't recognize the new rows as changed data. To insure that the dirty bit is set, you need to call DataTable.Rows.Add, but as mentioned this cannot be called using the row of another table as a parameter.

What to do? Don't use the row as a parameter to Add(). Instead, use the 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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM