2013-09-03 54 views
15

Tất cả các câu trả lời của bạn đều hữu ích. Cảm ơn tất cả những ai nỗ lực trả lời câu hỏi của tôi. Chúc mừng :)SqlConnection.Close() bên trong sử dụng câu lệnh

Tôi đang sử dụng mã này:

public void InsertMember(Member member) 
    { 
     string INSERT = "INSERT INTO Members (Name, Surname, EntryDate) VALUES (@Name, @Surname, @EntryDate)"; 

     using (sqlConnection = new SqlConnection(sqlConnectionString_WORK)) 
     { 
      sqlConnection.Open(); 

      using (SqlCommand sqlCommand = new SqlCommand(INSERT, sqlConnection)) 
      { 
       sqlCommand.Parameters.Add("@Name", SqlDbType.VarChar).Value = member.Name; 
       sqlCommand.Parameters.Add("@Surname", SqlDbType.VarChar).Value = member.Surname; 
       sqlCommand.Parameters.Add("@EntryDate", SqlDbType.Date).Value = member.EntryDate; 

       sqlCommand.ExecuteNonQuery(); 
      } 
     } 
    } 

Có sai nếu tôi không thêm sqlConnection.Close(); trước khi xử lý nó? Ý tôi là ... Nó không hiển thị bất kỳ lỗi nào, không có vấn đề gì cả ... Có tốt hơn để Đóng nó trước không? Nếu đúng thì tại sao?

+2

Các bằng tuyên bố sẽ 'Dispose' kết nối ngay cả trong trường hợp ngoại lệ, vì vậy bạn don 't thực sự cần một cuộc gọi 'Close' có – V4Vendetta

Trả lời

21

Không cần phải Close or Dispose khối using sẽ xử lý điều đó cho bạn.

Như đã trình bày từ MSDN:

Ví dụ sau tạo một SqlConnection, mở nó, hiển thị một số thuộc tính của nó. Kết nối được tự động đóng ở cuối của khối sử dụng.

private static void OpenSqlConnection(string connectionString) 
{ 
    using (SqlConnection connection = new SqlConnection(connectionString)) 
    { 
     connection.Open(); 
     Console.WriteLine("ServerVersion: {0}", connection.ServerVersion); 
     Console.WriteLine("State: {0}", connection.State); 
    } 
} 
+0

Đó là về' Close() ', không phải' Dispose() ':) – Matten

+0

@Matten - cảm ơn - chỉ cần chỉnh sửa. –

+1

Có OK không nếu mã có kết nối.Close(); ngay trước dấu ngoặc nhọn cuối cùng thứ hai của bạn '}'? Điều này sẽ ném một ngoại lệ khi khối sử dụng cố gắng đóng một kết nối đã được đóng bởi mã? – variable

1

Không, không sai. Các sqlConnection sẽ đóng kết nối sau khi nó sẽ vượt qua sử dụng khối và gọi phương pháp Vứt bỏ. SqlConnection.Dispose() bằng phương thức SqlConnection.Close().

Từ MSDN: Nếu SqlConnection nằm ngoài phạm vi, nó sẽ không bị đóng. Do đó, bạn phải đóng kết nối một cách rõ ràng bằng cách gọi Đóng hoặc Vứt bỏ. Đóng và Vứt bỏ có chức năng tương đương.

1

Bạn đang sử dụng Using sẽ Dispose() đối tượng cho bạn.

Nếu bạn lấy kết nối bên ngoài câu lệnh Using, thì có - bạn sẽ cần đóng kết nối khi hoàn tất.

1

Theo MSDN documentation for the Close method:

bạn phải đóng một cách rõ ràng các kết nối bằng cách gọi Đóng hoặc Vứt bỏ. ĐóngVứt bỏ có chức năng tương đương.

Do đó, hãy gọi Dispose (hoàn toàn như vậy, ngay cả khi sử dụng using) sẽ bao gồm các cơ sở của bạn như cũ.

Nó đáng chú ý, quá, tôi nghĩ rằng, mặc dù không cụ thể cho trường hợp của bạn, mà Close sẽ luôn luôn có hiệu quả được gọi khi điều được bọc trong một tuyên bố using - mà có thể không được trường hợp nên nó được bỏ qua và một ngoại lệ xảy ra mà không cần xử lý try/catch/finally phù hợp.

+0

Trong ví dụ nó nói: Ví dụ sau tạo SqlConnection, mở nó, hiển thị một số thuộc tính của nó. Kết nối được tự động đóng ở cuối khối sử dụng. –

+0

@DarrenDavies Chính xác. Nó rõ ràng hơn về chi tiết hơn nữa. –

1

Có sai không nếu tôi không thêm sqlConnection.Gần(); trước khi xử lý nó

Không, nó không miễn là bạn đang sử dụng kết nối của mình trong vòng Using. Khi bạn rời khỏi phạm vi sử dụng, Dispose sẽ được gọi để kết nối sql. sẽ đóng kết nối hiện có và giải phóng tất cả các tài nguyên.

2

Tuyên bố sử dụng là lần thử cuối cùng chặn và trong trường hợp của bạn, khối cuối cùng sẽ có cuộc gọi connection.Dispose(). Vì vậy, bạn không thực sự cần một tuyên bố độc lập connection.Close() ở đó.

Lợi thế là điều này đảm bảo việc xử lý ngay cả trong trường hợp ngoại lệ vì khối cuối cùng sẽ luôn chạy.

try 
{ 
sqlConnection.Open(); 
// .... 
} 
finally 
{ 
if(sqlConnection != null) 
     sqlConnection.Dispose(); 
} 
0

Đây là câu hỏi rất thú vị và không rõ ràng như nhiều người có thể nghĩ. Sử dụng câu lệnh sẽ hoạt động chính xác để kết nối chỉ khi tất cả các đối tượng sử dụng kết nối sẽ được xử lý. Một số thời gian trước, chúng tôi đã có một vấn đề với các kết nối mở trong máy chủ sql của chúng tôi. Mọi thứ đều ổn bởi vì các kết nối được sử dụng bên trong các câu lệnh, nhưng một trong các nhà phát triển đã tạo ra vài phương thức với SqlDataReader và không đóng nó một cách chính xác. Vì các kết nối đó không được giải phóng.

Lý do là cách thức hoạt động của bộ sưu tập rác. Dài câu chuyện ngắn - nó tạo ra một bản đồ của các đối tượng để xử lý và thực sự vứt bỏ chúng khi không có tham chiếu hoạt động cho các đối tượng.

3

using statement ensures that Dispose is called ngay cả khi xảy ra ngoại lệ trong khi bạn đang gọi các phương thức trên đối tượng. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; trên thực tế, đây là cách câu lệnh sử dụng là được dịch bởi trình biên dịch. MSDN

Vì vậy, cuối cùng dòng mã của bạn

using (sqlConnection = new SqlConnection(sqlConnectionString_WORK)) 

sẽ được chuyển đổi thành một bình thường try finally block bởi trình biên dịch gọi IDisposable object in the finally

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