2011-12-12 38 views
11

đến bây giờ tôi luôn luôn sử dụng một cấu trúc tương tự để lấy dữ liệu từ DB và điền vào một DataTableVứt bỏ lệnh SQL và đóng kết nối

public static DataTable GetByID(int testID) 
     { 
     DataTable table = new DataTable(); 
     string query = @"SELECT * FROM tbl_Test AS T WHERE T.testID = @testID"; 

     using (SqlConnection cn = new SqlConnection(Configuration.DefaultConnectionString)) 
     { 
      SqlCommand cmd = new SqlCommand(query, cn); 
      cmd.Parameters.Add("@testID", SqlDbType.Int).Value = testID; 

      cn.Open(); 
      table.Load(cmd.ExecuteReader()); 
     } 

     return table; 
    } 

Bây giờ tôi thấy một số cảnh báo trong phân tích xây dựng:

TestService. cs (37): CA2000: Microsoft.Reliability: Trong phương thức 'TestService.GetByID (int)', đối tượng 'table' không được xử lý dọc theo tất cả các đường dẫn ngoại lệ. Gọi System.IDisposable.Dispose trên đối tượng 'table' trước khi tất cả các tham chiếu đến nó nằm ngoài phạm vi.

TestService.cs (42): CA2000: Microsoft.Reliability: Trong phương thức 'TestService.GetByID (int)', hãy gọi System.IDisposable.Dispose trên đối tượng 'cmd' trước khi tất cả các tham chiếu đến nó nằm ngoài phạm vi.

Tôi có nên thay đổi mã của tôi trong

public static DataTable GetByID(int testID) 
    { 
     DataTable table = new DataTable(); 
     string query = @"SELECT * FROM tbl_Test AS T WHERE T.testID = @testID"; 

     using (SqlConnection cn = new SqlConnection(Configuration.DefaultConnectionString)) 
     { 
      using (SqlCommand cmd = new SqlCommand(query, cn)) 
      { 
       cmd.Parameters.Add("@testID", SqlDbType.Int).Value = testID; 

       cn.Open(); 
       table.Load(cmd.ExecuteReader()); 
      } 
     } 

     return table; 
    } 

Phải làm gì với đối tượng DataTable? Có thực hành tốt để đặt SqlCommand bên trong việc sử dụng không?

Cảm ơn

Cheers

+0

Yes. Mã của bạn là chính xác ngay bây giờ. Luôn loại bỏ lớp thực hiện IDisposable. Nhưng SqlDataReader cũng dùng một lần? – lnu

+0

Bạn có vứt bỏ DataTable mà bạn quay trở lại không? – Kangkan

+0

Tôi tin rằng người đọc là dùng một lần có, và có lẽ đó là vấn đề WRT bảng không được xử lý vì nó giữ một người đọc mà không được đóng một cách rõ ràng, mặc dù tôi hy vọng nó sẽ được đóng kín khi cmd được xử lý. –

Trả lời

7

Bạn cũng nên làm điều này:

using (SqlDataReader reader = 
      cmd.ExecuteReader 
       (CommandBehavior.CloseConnection)) 
     { 
      table.Load(reader); 
     } 

khi tải bảng

+0

Đây là lần đầu tiên tôi thấy cách tiếp cận này. Tại sao trên MSDN không có gì tương tự thậm chí được đề cập? – MaiOM

+0

Đó là một tùy chọn. MSDN chỉ hiển thị một trường hợp mẫu (đơn giản).Và, có bạn nên vứt bỏ các datatable quá. – lnu

+0

Cũng như tôi thường là các ứng dụng web, khi nào tôi nên gọi việc xử lý DataTable đã sử dụng? Giả sử rằng khi tải trang, tôi kết hợp lời gọi phương thức đó với lưới và Liên kết nó. Nơi để gọi phương pháp vứt bỏ? Cảm ơn – MaiOM

3
  • Người gọi của phương pháp này nên gọi dispose của DataTable trả về khi nó được thực hiện sử dụng nó.
  • Có, đó là một thực hành tốt để đặt SqlCommand bên trong sử dụng.
+2

Cũng như tôi thường là các ứng dụng web, khi nào tôi nên gọi việc xử lý DataTable đã sử dụng? Giả sử rằng khi tải trang, tôi kết hợp lời gọi phương thức đó với lưới và Liên kết nó. Nơi để gọi phương pháp vứt bỏ? Cảm ơn – MaiOM

1

Để "khắc phục" sự cố của bạn với DataTable, có lẽ bạn có thể sửa đổi chức năng của mình.

public static void GetByID(DataTable table, int testID) 
{ 
    // bla bla bla 
} 


// calling the function 
using(DataTable table = new DataTable()) 
{ 
    TestService.GetByID(table, 5); 
} 

Không nói đây là giải pháp tối ưu nhưng sẽ giải quyết khiếu nại.

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