简体   繁体   中英

Update the dataset after rows changed

Scenario:

  1. Excel file is read and displayed in datagrid.
  2. Values in sql server must be updated if excel values are different.
  3. Table in Sql server don't have primary key

After all these steps, when I am about to update the table, it throws the error saying "Update requires a valid UpdateCommand when passed DataRow collection with modified rows."

There is no primary key. So I need to use update command. BUt how and what would be in update command? importdata is dictionary where data from excel are stored. PLz help!!! What should I do now? I have No idea....

foreach (DataColumn column in ds.Tables[0].Columns)
{
    string fieldName = column.ColumnName;
    string fieldNameValueE = string.Empty;
    if (importdata.ContainsKey(fieldName))
    {
        fieldNameValueE = importdata[fieldName];
        foreach (DataRow dr in ds.Tables[0].Rows)
        {
            string fieldNameValueD = dr[fieldName].ToString();
            if (fieldNameValueD != fieldNameValueE)
            {
                dr[fieldName] = fieldNameValueE;

            }
        }

    }

}

da.Update(ds);
connection.Close();    

Use SqlCommandBuilder.

After setting up your DataAdapter, initialize a command builder. Then use the SqlCommandBuilder update feature.

SqlCommandBuilder cb = new SqlCommandBuilder(da);

//Do your other work updating the data

cb.DataAdapter.Update(ds);

That should do the trick!

Edit:

As BigM pointed out, your table needs to have a primary key for the SqlCommandBuilder to work. If however, you can't modify the actual SQL table and mark one of the fields as a Primary Key and you also know that one of the fields is unique, you can add a Primary Key to your DataSet table like this:

DataColumn[] pk1 = new DataColumn[1];
pk1[0] = ds.Tables["TableName"].Columns[0];
ds.Tables["TableName"].PrimaryKey = pk1;

This gives your "in memory" table a primary key so that the SqlCommandBuilder can do its work.

Warning:

You must be sure that the values in the column you mark as primary key are actually unique.

So, let's say we were dealing with a table that had a primary key:

CREATE TABLE TableA
{
    FieldA INT PRIMARY KEY IDENTITY(1, 1),
    FieldB VARCHAR(256) NULL,
    FieldC VARCHAR(256) NOT NULL,
}

If you were to use the SqlCommandBuilder (which you cannot because you don't have a primary key), it would build a statement a bit like this:

UPDATE TableA
    SET FieldB = @p1,
        FieldC = @p2
WHERE (FieldA = @p3 AND
    ((FieldB IS NULL AND @p4 IS NULL) OR (FieldB = @p5)) AND
    FieldC = @p6)

So, you're going to need to build an UPDATE statement that's very similar to do it the way they do. But one thing you need to remember is it's not just the statement, you also have to add all of the parameters to the command that you build - and that's going to become pretty cumbersome.

So, I have two recommendations for you:

  1. Make a primary key on the table.
  2. Issue an ExecuteNonQuery in every iteration of the loop.

The second recommendation would look like this:

foreach (DataColumn column in ds.Tables[0].Columns)
{
    string fieldName = column.ColumnName;
    string fieldNameValueE = string.Empty;
    if (importdata.ContainsKey(fieldName))
    {
        fieldNameValueE = importdata[fieldName];
        foreach (DataRow dr in ds.Tables[0].Rows)
        {
            string fieldNameValueD = dr[fieldName].ToString();
            if (fieldNameValueD != fieldNameValueE)
            {
                dr[fieldName] = fieldNameValueE;
            }

            var cmd = new SqlCommand(string.Format(
                "UPDATE importdata SET {0} = {1} WHERE fielda = @fielda AND fieldb = @fieldb ...",
                fieldName, fieldNameValueE), connectionObject);
            cmd.Parameters.AddWithValue(@fielda, dr["fielda", DataRowVersion.Original]);
            cmd.Parameters.AddWithValue(@fieldb, dr["fieldb", DataRowVersion.Original]);

            cmd.ExecuteNonQuery();
        }
    }
}

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