社内アプリケーションの例外情報を記録するロガーがあります。
SQL 例外をログに記録するとき、例外の原因となった実際のクエリを確認できれば非常に便利です。
これを達成する方法はありますか?
社内アプリケーションの例外情報を記録するロガーがあります。
SQL 例外をログに記録するとき、例外の原因となった実際のクエリを確認できれば非常に便利です。
これを達成する方法はありますか?
は、例外の原因となったSqlException
への参照を保持していません。SqlCommand
あなたのロガーでは、これを行う方法はありません。あなたができることは、を実行するメソッドで SqlException をキャッチし、SqlCommand
それをより説明的な例外でラップすることです。例:
using (var command = new SqlCommand(connection, "dbo.MyProc"))
{
try
{
command.Execute();
}
catch (DbException ex)
{
throw new InvalidOperationException(ex.Message + " - " + command.Text, ex);
}
}
このようにして、このより表現力豊かな例外をログに記録できます。
SQL 例外をスローすることはできません。彼は、command.CommandText を含む新しい例外をスローするつもりだったと思います。
これを行う最も DRY な方法は、デリゲート、sql コマンド テキスト、およびパラメーター化されたクエリを使用している場合はオプションで sql パラメーター配列を受け取るヘルパー メソッドを記述することです。デリゲートを try catch ブロックでラップし、例外が発生したときに LogError メソッドを呼び出します。
protected virtual TResult ExecuteAndLogError<TResult>(Func<TResult> code, string sql, SqlParameterCollection parameters = null)
{
try {
if ((System.Diagnostics.Debugger.IsAttached))
PrintSqlToDebug(sql, parameters);
return code();
} catch (Exception ex) {
LogError(sql, parameters, ex);
throw;
}
}
私の SQL コードでは、データ層ヘルパー メソッドから ExecuteAndLogError を呼び出します。すべてのデータ レイヤー メソッドが ExecuteAndLogError を呼び出すため、SQL エラーをログに記録するコード セクションは 1 つだけです。
public virtual DataTable ExecuteDataTable(SqlCommand command, params SqlParameter[] parameters)
{
command.Parameters.AddRange(parameters);
DataTable table = new DataTable();
using (SqlDataAdapter adapter = new SqlDataAdapter(command)) {
using (command) {
ExecuteAndLogError(() => adapter.Fill(table), command.CommandText, command.Parameters);
}
}
return table;
}
次のように使用できますrepo.ExecuteDataTable("SELECT * FROM Users");
。例外が発生した場合は、LogError メソッドを実装して追加のログを実行できます。
このコードの一部は、サブテキスト ブログ データ レイヤー クラスから取得されました。