チュートリアルに従って、.Net SqlDataAdapter.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)))
出力では、最初の行の更新の実行が終了した後、コマンドがどこかで変更されているように見えますが、2 番目の行の更新の前に、これが発生する原因はわかりません。誰かが手がかりを提供したり、私が間違っていることを見つけたりできますか? 上で示したように、これは正常に機能していましたが、理由もなく壊れたように見えました。
アップデート
StringBuilder 操作を完全に削除しました (RowUpdating イベントは、更新コマンドの出力のみで構成されていました)、それでも奇妙な動作が見られました。
ただし、コード内を少し移動することで問題を軽減できたと思います。特に、アダプターにさまざまなコマンドを設定した後、RowUpdating イベントを設定しました。これが問題に影響を与えている理由はわかりませんが(したがって、これを回答として挙げていません)、少なくとも今のところは修正されているようです。