2011-10-21 38 views
7

Tôi đã gói các đối tượng OracleConnection và OracleCommand của mình trong các câu lệnh USING trong một thời gian, tuy nhiên, sau khi chạy trình phân tích mã, tôi khám phá ra rằng OracleParameter cũng triển khai IDisposable. Mã sau có chính xác không? Có một kỹ thuật tốt hơn cho khả năng đọc hoặc cấu trúc? Thoạt nhìn, nó dường như có vẻ lộn xộn với các câu lệnh USING:C# IDisposable Sử dụng: Thực hành tốt nhất

using (OracleConnection conn = new OracleConnection(connectionstring)) 
{ 
    conn.Open(); 
    using (OracleCommand cmd = new OracleCommand(sql, conn)) 
    { 
     cmd.BindByName = true; 

     using (OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, System.Data.ParameterDirection.Input)) 
     { 
      param1.Value = int.Parse(value1); 
      cmd.Parameters.Add(param1); 
     } 

     using (OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, System.Data.ParameterDirection.Input)) 
     { 
      param2.Value = value2; 
      cmd.Parameters.Add(param2); 
     } 

     using (OracleDataReader dr = cmd.ExecuteReader()) 
     { 
      // loop data here... 
     } 
    } 
} 

Trả lời

7

Bạn muốn vứt bỏ các thông số chỉ ở cuối của việc sử dụng chúng, kể cả trong các truy vấn (và có thể đọc các kết quả):

using (OracleConnection conn = new OracleConnection(connectionstring)) 
{ 
    conn.Open(); 
    using (OracleCommand cmd = new OracleCommand(sql, conn)) 
    { 
     cmd.BindByName = true; 

     using (OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, System.Data.ParameterDirection.Input)) 
     using (OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, System.Data.ParameterDirection.Input)) 
     { 
      param1.Value = int.Parse(value1); 
      cmd.Parameters.Add(param1); 
      param2.Value = value2; 
      cmd.Parameters.Add(param2); 

      using (OracleDataReader dr = cmd.ExecuteReader()) 
      { 
       // loop data here... 
      } 
     } 
    } 
} 

Chú ý rằng bạn có thể đặt nhiều using báo cáo trong một hàng. Điều này là do, như tuyên bố số if,

  1. Tuyên bố using được coi là một tuyên bố đơn giản (ngay cả với một khối); và
  2. Câu hỏi using có thể là một khối hoặc một câu lệnh bên dưới.
+0

Mặc dù có nhiều câu trả lời tương tự, tôi đánh giá cao rằng bạn đã cung cấp cả ví dụ và bình luận. – Shawn

+0

Cảm ơn! Vui vì tôi có thể giúp đỡ. :-) –

1

Tôi không chắc chắn rằng nó sẽ hoạt động bình thường. Hãy xem xét rằng vào cuối của việc sử dụng, cả hai thông số cần phải được xử lý. Thực tế là đối tượng cmd.Parameters của bạn vẫn giữ một tham chiếu đến chúng không loại trừ những gì có thể xảy ra trong phương thức Xử lý số OracleParameter. Đối với tất cả các mục đích chuyên sâu, nhà phát triển của đối tượng cụ thể đó có thể đang xóa các trường mà OracleCommand của bạn dự kiến ​​sẽ được lấp đầy.

Có một số mối nguy hiểm ở đó. Nếu bạn hoàn toàn chắc chắn bạn muốn vứt bỏ OracleParameters đúng cách của mình, tôi khuyên bạn nên vứt bỏ chúng sau khi sử dụng OracleDataReader.

Hãy nhớ rằng bạn thường gọi số Dispose khi bạn sử dụng xong đối tượng. Bạn đang nói với nó để phát hành tất cả các nguồn lực mà nó đang giữ lại hồ bơi. Nếu bạn không thực hiện bằng cách sử dụng một đối tượng, không vứt bỏ nó sớm.

0

Không có điều này là không chính xác vì bạn đang xử lý các thông số ngay cả trước khi bạn sử dụng chúng.

Thay vào đó bạn nên để nó thích này

OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, System.Data.ParameterDirection.Input); 

param1.Value = int.Parse(value1); 
cmd.Parameters.Add(param1); 


OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, System.Data.ParameterDirection.Input); 

param2.Value = value2; 
cmd.Parameters.Add(param2); 


using (OracleDataReader dr = cmd.ExecuteReader()) 
{ 
    // loop data here... 
} 

param1.dispose(); 
param2.dispose(); 
1
using (OracleConnection conn = new OracleConnection(connectionstring)) 
using (OracleCommand cmd = new OracleCommand(sql, conn)) 
using (OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, 
     System.Data.ParameterDirection.Input)) 
using (OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, 
     System.Data.ParameterDirection.Input)) 
} 
    conn.Open(); 
    cmd.BindByName = true; 

    param1.Value = int.Parse(value1); 
    cmd.Parameters.Add(param1); 

    param2.Value = value2; 
    cmd.Parameters.Add(param2); 

    using (OracleDataReader dr = cmd.ExecuteReader()) 
    { 
     // loop data here... 
    } 
} 
0

bạn có thể xem mã nguồn kết nối và lệnh, nó xử lý các thông số? nếu kết nối hoặc lệnh đối tượng vứt bỏ mẫu bao bọc các thông số và vứt bỏ chúng khi chúng được xử lý. bạn nên lo lắng về nó. mà tôi nghĩ rằng nó sẽ/nên.

0

Mã này không chính xác. các thông số bạn tạo chúng vẫn được sử dụng ngoài phạm vi câu lệnh using vì bạn thêm chúng vào bộ sưu tập tham số, nhưng câu lệnh using sẽ gọi số Dispose trên các thông số khi kiểm soát rời khỏi phạm vi. Có nghĩa là khi thời gian sẽ đến sử dụng các thông số bên trong theya lệnh sẽ được disoised của đã

0

Theo MSDN, bạn chỉ cần sử dụng using cho ConnectionDataReader đối tượng. Tôi chưa bao giờ thấy using (hoặc .Dispose()) được sử dụng với các đối tượng tham số ADO.NET. Nếu điều này là cần thiết hoặc thậm chí là mong muốn, tôi nghĩ nó sẽ xuất hiện một thời gian trong vòng 10 năm qua.

+2

MSDN đang nói về các đối tượng được cung cấp bởi BCL. Việc triển khai thực hiện các yêu cầu này của Oracle có thể rất cần thiết Xử lý các tham số. Tại sao họ sẽ thực hiện IDisposable nếu họ không có ý định được xử lý? –

+0

Hoặc họ rất tốt có thể không. Tôi chưa bao giờ thấy bất kỳ mã ADO.NET nào (đối với việc triển khai của Oracle hoặc của bất kỳ ai khác) hoặc được gọi là Dispose() trên một đối tượng tham số hoặc đặt nó trong một khối 'using'. Một lần nữa, nếu xử lý các thông số là cần thiết, điều này sẽ được nuôi dưỡng đầu của nó một thời gian dài trước đây. – MusiGenesis

+2

Vì vậy, lời khuyên của bạn là, mặc dù một đối tượng thực hiện IDisposble, không vứt bỏ nó, trừ khi nó được biết đến là một vấn đề? Nghe như lời khuyên xấu cho tôi. –

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