Using an SQL Data Adapter to update and insert rows doesn't update (only inserts)

眉间皱痕 提交于 2019-12-11 23:14:49

问题


I am just playing around with this at the moment, ultimately I want to read a CSV file into memory and then insert the records into an SQL database. Existing records should be updated, records that are missing should be added. Records that don't exist in the new CSV shouldn't be deleted, however.

I've been playing around the example from the MSDN library. I understand that the SqlDataAdapter can perform bulk updates quite quickly.

I created a little mock app with a table called TempTestTable that has TempTestTableId, Age, and Name columns. I wrote this (based on the MSDN Article):

using (SqlConnection connection =
   new SqlConnection("data source=localhost;initial catalog=fishsticks;integrated security=True;MultipleActiveResultSets=True;"))
{
    SqlDataAdapter dataAdpater = new SqlDataAdapter(
      "SELECT temptesttableid, Age, Name FROM TempTestTable",
      connection);

    dataAdpater.UpdateCommand = new SqlCommand(
       "UPDATE TempTestTable SET Age = @Age, Name = @Name " +
       "WHERE TempTestTableId = @TempTestTableId", connection);

    dataAdpater.InsertCommand = new SqlCommand(
       "INSERT INTO TempTestTable (Age, Name) " +
       "VALUES (@Age, @Name)", connection);

    SqlParameter parameter = dataAdpater.UpdateCommand.Parameters.Add(
       "@TempTestTableId", SqlDbType.Int);

    dataAdpater.InsertCommand.Parameters.Add(
      "@Age", SqlDbType.Int, 10, "Age");

    dataAdpater.InsertCommand.Parameters.Add(
      "@Name", SqlDbType.NVarChar, 50, "Name");

    dataAdpater.UpdateCommand.Parameters.Add(
      "@Age", SqlDbType.Int, 10, "Age");

    dataAdpater.UpdateCommand.Parameters.Add(
      "@Name", SqlDbType.NVarChar, 50, "Name");

    parameter.SourceColumn = "TempTestTableId";
    parameter.SourceVersion = DataRowVersion.Original;

    DataTable tempTestTable = new DataTable();

    tempTestTable.Columns.Add("Age");
    tempTestTable.Columns.Add("Name");
    tempTestTable.Columns.Add("TempTestTableId");

    var row1 = tempTestTable.NewRow();

    row1["Age"] = 10;
    row1["Name"] = "Smith";
    row1["TempTestTableId"] = 1;

    var row2 = tempTestTable.NewRow();

    row2["Age"] = 40;
    row2["Name"] = "Jones";
    row2["TempTestTableId"] = 2;

    tempTestTable.Rows.Add(row1);
    tempTestTable.Rows.Add(row2);

    dataAdpater.Update(tempTestTable);

There is already a record in the database with TempTestTableId = 1, so the idea was that in theory it would update that record, as well as insert a new record with ID 2. However, when I run the code, it inserts both items.

Any ideas?


回答1:


No, the DataAdapter will just look at the DataRow's RowState property. If it's Added the InsertCommand will be executed, if it's Modified the UpdateCommand will be executed. You have to load this row into the table from the database first.

You can fill an empty DataTable with a DataAdapter and your SelectCommand including two parameters. If the table is empty you can add the DataRow manually, otherwise you can modify the rows with the updated values (if any) and call dataAdpater.Update(tempTestTable).

Here's an example (untested):

SqlDataAdapter dataAdpater = new SqlDataAdapter(
  "SELECT temptesttableid, Age, Name FROM TempTestTable WHERE Name = @Name",
  connection);

DataTable testTable = new DataTable();
// note that you should use an available csv-parser instead
foreach (string line in File.ReadAllLines(path))
{ 
    string[] columns = line.Split(new char[]{'\t'}, StringSplitOptions.None);
    if(columns.Length >= 2)
    {
        string name = columns[0].Trim();
        string ageStr = columns[1].Trim();
        int age;
        if (int.TryParse(ageStr, out age))
        {
            dataAdpater.SelectCommand.Parameters.AddWithValue("@Name", name);
            int rowsAdded = dataAdpater.Fill(testTable);
            if (rowsAdded == 0)
            {
                testTable.Rows.Add(name, age);
            }
            else
            {
                // update values?
            }
        }
    }
}
dataAdpater.Update(testTable);


来源:https://stackoverflow.com/questions/21239060/using-an-sql-data-adapter-to-update-and-insert-rows-doesnt-update-only-inserts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!