Reputation: 35
Scenario:
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();
Upvotes: 0
Views: 1696
Reputation: 1499
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.
Upvotes: 0
Reputation: 67898
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:
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();
}
}
}
Upvotes: 1