C# 获取导致SQLException的查询/命令文本

C# 获取导致SQLException的查询/命令文本,c#,sqlexception,C#,Sqlexception,我有一个记录器,记录我们内部应用程序的异常信息 当我们记录SQL异常时,如果我们能够看到导致异常的实际查询,那将非常有用 有什么方法可以做到这一点吗?SqlException没有引用导致异常的SqlCommand。在您的记录器中,无法执行此操作。您可以在执行SqlCommand的方法中捕获SqlException,并将其包装为更具描述性的异常。例如: using (var command = new SqlCommand(connection, "dbo.MyProc")) { try

我有一个记录器,记录我们内部应用程序的异常信息

当我们记录SQL异常时,如果我们能够看到导致异常的实际查询,那将非常有用


有什么方法可以做到这一点吗?

SqlException没有引用导致异常的
SqlCommand
。在您的记录器中,无法执行此操作。您可以在执行
SqlCommand
的方法中捕获SqlException,并将其包装为更具描述性的异常。例如:

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的新异常。

最简单的方法是编写一个助手方法,该方法接受委托、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;
    }
} 
}

您可以这样使用它:
repo.ExecuteDataTable(“SELECT*FROM Users”)如果出现异常,可以实现LogError方法来执行其他日志记录


这段代码中的一些代码取自Subtext Blog数据层类。

作为一个简单的破解,您还可以将sql添加为异常数据的一部分。这将保留原始异常,但也会提供额外的sql消息

using (var command = new SqlCommand(connection, "dbo.MyProc"))
{
   try
   {
      command.Execute();
   }
   catch (SqlException ex)
   {
      ex.Data.Add("Sql",command.Text);
      throw ex
   }
}

这样会丢失原始异常的堆栈跟踪吗?不会,因为新异常会包装旧异常。
using (var command = new SqlCommand(connection, "dbo.MyProc"))
{
   try
   {
      command.Execute();
   }
   catch (SqlException ex)
   {
      ex.Data.Add("Sql",command.Text);
      throw ex
   }
}