2010-08-02 27 views
11

Tôi biết tôi đã hỏi một câu hỏi liên quan trước đó. Tôi chỉ có một suy nghĩ khác.sử dụng trên SQLDataReader

using (SqlConnection conn = new SqlConnection('blah blah')) 
{ 
    using(SqlCommand cmd = new SqlCommand(sqlStatement, conn)) 
    { 
     conn.open(); 

     // *** do I need to put this in using as well? *** 
     SqlDataReader dr = cmd.ExecuteReader() 
     { 
      While(dr.Read()) 
      { 
       //read here 
      } 
     } 
    } 
} 

Đối số là: Kể từ khi đối tượng SqlDataReaderdr là KHÔNG PHẢI LÀ MỘT OBJECT mới như kết nối hoặc lệnh đối tượng, nó chỉ đơn giản là một tham chiếu trỏ đến các phương pháp cmd.ExecuteReader(), tôi cần phải đưa người đọc bên trong một using. (Bây giờ dựa trên bài trước của tôi, đó là sự hiểu biết của tôi rằng bất kỳ đối tượng sử dụng IDisposable cần phải được đặt trong một using, và SQLDataReader kế thừa từ IDisposable, vì vậy tôi cần phải đặt nó. Tôi có đúng trong bản án của tôi?) Tôi chỉ nhầm lẫn vì nó không phải là một đối tượng mới, nó sẽ gây ra bất kỳ vấn đề trong việc xử lý một đối tượng mà chỉ đơn giản là một con trỏ tham chiếu đến lệnh?

Rất cám ơn

+0

"cmd.ExecuteReader" là một loại phương pháp tham khảo. "cmd.ExecuteReader()" (dấu ngoặc thông báo) là một cuộc gọi phương thức. –

Trả lời

26

Tôi nghĩ bạn đã nhầm. Các dr là một tham chiếu đến đối tượng trả về bởi cmd.ExecuteReader, mà sẽ là một đối tượng mới. Trong ví dụ của bạn, không có gì sẽ xử lý dr, vì vậy có, nó cần phải ở trong một số using hoặc được xử lý thủ công.

Bản án của bạn về IDisposable người triển khai cần để ở trong using không chính xác. Chúng sẽ hoạt động tốt bên ngoài. Câu lệnh using chỉ là cú pháp cú pháp cho số try ... finally. Những điều cần thực hiện IDisposable phải có số Dispose được gọi là vì chúng báo hiệu rằng chúng cần phải loại bỏ trạng thái nhất định theo cách xác định.

Lưu ý rằng nếu bạn không gọi Dispose, nó không phải luôn luôn là một vấn đề. Một số đối tượng cũng thực hiện finalizer, sẽ được kích hoạt bởi bộ thu gom rác. Nếu họ không thực hiện finalizer, họ có thể rời khỏi bộ nhớ không được quản lý unreclaimed. Điều này sẽ vẫn không được khôi phục cho đến khi ứng dụng của bạn đóng. Tất cả bộ nhớ được quản lý cuối cùng được khai hoang, trừ khi nó không phải là dễ hiểu đối với việc thu gom rác thải.

Re-viết:

using (SqlConnection conn = new SqlConnection('blah blah')) 
using(SqlCommand cmd = new SqlCommand(sqlStatement, conn)) 
{ 
    conn.open(); 
    using (SqlDataReader dr = cmd.ExecuteReader()) 
    { 
     while (dr.Read()) 
     { 
      //read here 
     } 
    } 
} 
+0

vâng tôi hiểu rằng việc sử dụng chỉ đơn giản là dịch thành một try..finally chặn và tôi cũng có thể gọi là xử lý tự của tôi. Nhưng tôi nghĩ tốt hơn là nên tạo thói quen bao bọc khối bên trong việc sử dụng vì tôi có thể có xu hướng quên bỏ đoạn mã trong thử ... một cách hoàn hảo. Cảm ơn vi đa trả lơi. :) – xeshu

+0

Đó là OK :-) Tôi sẽ đề cập đến nó cũng như SqlDataReader là một đối tượng mới, hoặc ít nhất là một tham chiếu đến một đối tượng được trả về bởi cuộc gọi phương thức, nó không phải là một tham chiếu đến phương thức. Chỉ cần đề cập bởi vì bạn đã làm cho điểm đó trong chữ in hoa và nó không chính xác. Sự khác biệt duy nhất giữa người đọc và kết nối/lệnh là bạn đã khởi tạo kết nối/lệnh, nhưng bạn không khởi tạo trình đọc. Cuối cùng, bạn vẫn có tham chiếu đến tất cả các đối tượng - cho dù bạn đã khởi tạo chúng hay chưa. –

+0

À vâng. Lỗi của tôi! :) – xeshu

2

Bạn nên quấn đọc dữ liệu trong một tuyên bố sử dụng như là phương thức ExecuteReader đang tạo ra một trường hợp đầu đọc dữ liệu mới cũng nên được xử lý.

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