Получите Query / CommandText, который вызвал SQLException - PullRequest
11 голосов
/ 03 июня 2010

У меня есть регистратор, который записывает информацию об исключениях для наших внутренних приложений.

Когда мы регистрируем исключения SQL, было бы очень полезно, если бы мы могли видеть фактический запрос, вызвавший исключение.

Есть ли способ, которым мы можем этого достичь?

Ответы [ 3 ]

16 голосов
/ 03 июня 2010

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

Таким образом, вы можете записать это более выразительное исключение.

2 голосов
/ 14 июня 2011

Вы не можете бросить исключение sql. Я думаю, что он хотел создать новое исключение, содержащее команду. CommandText.

0 голосов
/ 20 сентября 2011

Самый сухой способ сделать это - написать вспомогательный метод, который принимает делегат, текст команды 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 существует только один раздел кода.

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 для выполнения дополнительной регистрации.

Часть этого кода была взята из классов слоя данных Subtext Blog.

...