1

我按照教程使用 .Net SqlDataAdapater.Update 方法生成表更新脚本。但是,似乎 SqlCommands 在某处发生突变,以至于语法上不正确。对我来说更奇怪的是,这个问题似乎是突然冒出来的。

...
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);
}

输出:

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)))

所以你可以看到问题是生成了一个不正确的脚本:

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

输出看起来像是在第一行更新完成执行之后命令在某处发生了变异,但是第二行更新之前,我不知道是什么导致这种情况发生。谁能提供任何线索或发现我做错了什么?正如我上面指出的,这工作正常,然后似乎没有理由就坏了。

更新

我完全删除了 StringBuilder 操作(RowUpdating 事件包含打印出更新命令),但我仍然看到了奇怪的行为。

但是,我相信我能够通过在我的代码中移动一些东西来缓解这个问题。除此之外,我在适配器上设置了各种命令后设置了 RowUpdating 事件。我想我不确定为什么这会影响问题(因此,我没有将其列为答案),但至少现在它似乎正在解决问题。

4

0 回答 0