1

I followed a tutorial to use the .Net SqlDataAdapater.Update method to generate a table update script. However, it appears that somewhere along the way the SqlCommands are getting mutated in such a way as to be syntactically incorrect. What is even stranger to me is that this problem seems to have popped up out of nowhere.

...
dataAdapter.RowUpdating += (sender, updatingEvent) => AppendToTableDataString(updatingEvent, tableDataStringBuilder);
var cmdBuilder = new SqlCommandBuilder(dataAdapter);
dataAdapter.DeleteCommand = cmdBuilder.GetDeleteCommand();
dataAdapter.InsertCommand = cmdBuilder.GetInsertCommand();
dataAdapter.UpdateCommand = cmdBuilder.GetUpdateCommand();
Console.WriteLine("Before call to Update: " + dataAdapter.UpdateCommand.CommandText);
dataAdapter.Update(DataTable);
Console.WriteLine("After call to Update: " + dataAdapter.UpdateCommand.CommandText);
...

private static void AppendToTableDataString(SqlRowUpdatingEventArgs updatingEvent, StringBuilder tableDataBuilder)
{
  if (updatingEvent.Command == null)
  {
    return;
  }

  Console.WriteLine("Before appending to StringBuilder: " + updatingEvent.Command.CommandText);
            tableDataBuilder.Append(updatingEvent.Command.Parameters.Cast<SqlParameter>()
                                    .Aggregate(updatingEvent.Command.CommandText, (current, aParameter) =>
                                               current.Replace(aParameter.ParameterName, aParameter.Value.ToString())) + Environment.NewLine);
  Console.WriteLine("After appending to StringBuilder: " + updatingEvent.Command.CommandText);
}

Output:

Before call to Update: UPDATE [schema].[table] SET [Id] = @p1, [Num] = @p2 WHERE (([Id] = @p3) AND ((@p4 = 1 AND [Num] IS NULL) OR ([Num] = @p5)))
Before appending to StringBuilder: UPDATE [schema].[table] SET [Id] = @p1, [Num] = @p2 WHERE (([Id] = @p3) AND ((@p4 = 1 AND [Num] IS NULL) OR ([Num] = @p5)))
After appending to StringBuilder: UPDATE [schema].[table] SET [Id] = @p1, [Num] = @p2 WHERE (([Id] = @p3) AND ((@p4 = 1 AND [Num] IS NULL) OR ([Num] = @p5)))
Before appending to StringBuilder: UPDATE [schema].[table] WHERE (([Id] = @p1) AND ((@p2 = 1 AND [Num] IS NULL) OR ([Num] = @p3)))
After appending to StringBuilder: UPDATE [schema].[table] WHERE (([Id] = @p1) AND ((@p2 = 1 AND [Num] IS NULL) OR ([Num] = @p3)))
Before appending to StringBuilder: UPDATE [schema].[table] WHERE (([Id] = @p1) AND ((@p2 = 1 AND [Num] IS NULL) OR ([Num] = @p3)))
After appending to StringBuilder: UPDATE [schema].[table] WHERE (([Id] = @p1) AND ((@p2 = 1 AND [Num] IS NULL) OR ([Num] = @p3)))
After call to Update: UPDATE [schema].[table] WHERE (([Id] = @p1) AND ((@p2 = 1 AND [Num] IS NULL) OR ([Num] = @p3)))

So you can see that the problem is that an incorrect script is being generated:

UPDATE [schema].[table] WHERE (([Id] = @p1) AND ((@p2 = 1 AND [Num] IS NULL) OR ([Num] = @p3)))

The output makes it look like the command is getting mutated somewhere after the first row update finishes executing, but before the second row update, however, I have no idea what would be causing this to happen. Can anyone offer any clues or spot what I'm doing wrong? As I indicate above, this was working fine and then seemingly seemed to break w/o reason.

UPDATE

I completely removed the StringBuilder operations (the RowUpdating event consisted solely of printing out the updating command), and I still saw the weird behavior.

However, I believe I was able to mitigate the problem by moving things around in my code a bit. Among other things, I set the RowUpdating event after setting the various commands on the adapter. I guess I'm not sure why this is affecting the problem (hence, I'm not listing this as an answer), but it appears to be fixing things for now at least.

Dan Forbes
  • 2,734
  • 3
  • 30
  • 60

0 Answers0