2010-06-03 23 views
9

Tôi có một trình ghi nhật ký ghi lại thông tin ngoại lệ cho các ứng dụng trong nhà của chúng tôi.Lấy Query/CommandText gây ra SQLException

Khi chúng tôi ghi lại các ngoại lệ SQL, nó sẽ cực kỳ hữu ích nếu chúng ta có thể thấy truy vấn thực tế gây ra ngoại lệ.

Có cách nào chúng ta có thể đạt được điều này không?

Trả lời

11

SqlException không giữ tham chiếu đến SqlCommand gây ra ngoại lệ. Trong logger của bạn không có cách nào để làm điều này. Những gì bạn có thể làm là bắt SqlException trong phương thức thực hiện SqlCommand và bọc nó trong một ngoại lệ mô tả hơn. Ví dụ:

using (var command = new SqlCommand(connection, "dbo.MyProc")) 
{ 
    try 
    { 
     command.Execute(); 
    } 
    catch (DbException ex) 
    { 
     throw new InvalidOperationException(ex.Message + " - " + command.Text, ex); 
    } 
} 

Bằng cách này bạn có thể ghi lại ngoại lệ rõ ràng hơn này.

2

Bạn KHÔNG thể ném ngoại lệ sql. Tôi nghĩ rằng ông có nghĩa là để ném một ngoại lệ mới có chứa lệnh.CommandText.

0

Cách DRYest để thực hiện việc này là viết phương thức trợ giúp lấy đại biểu, văn bản lệnh sql và tùy chọn mảng tham số sql nếu bạn đang sử dụng truy vấn tham số. Quấn các đại biểu trong một khối catch và gọi phương thức LogError khi có một ngoại lệ:

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

Trong mã SQL của tôi, tôi gọi ExecuteAndLogError từ các phương thức helper lớp dữ liệu. Tất cả các phương thức lớp dữ liệu gọi ExecuteAndLogError, vì vậy chỉ có một phần mã để ghi lại các lỗi 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; 

}

Bạn có thể sử dụng nó như thế này: repo.ExecuteDataTable("SELECT * FROM Users"); Nếu có một ngoại lệ, bạn có thể thực hiện phương pháp LogError để thực hiện thêm khai thác gỗ.

Một số mã này được lấy từ các lớp lớp dữ liệu Blog Subtext.

Các vấn đề liên quan