2012-09-19 15 views
8

Prendiamo il seguente esempio ...SqlCommand (istruzione using/problema Smaltimento)

 Using cn As New SqlConnection(ConnectionString) 
      Try 
       Dim cmd As SqlCommand = New SqlCommand 
       With cmd 
        .Connection = cn 
        .Connection.Open() 
        .CommandText = "dbo.GetCustomerByID" 
        .CommandType = CommandType.StoredProcedure 
        .Parameters.Add("@CustomerID", SqlDbType.Int, 4) 
        .Parameters("@CustomerID").Value = CustomerID 
       End With 

       da = New SqlDataAdapter(cmd) 
       da.Fill(ds, "Customer") 
      Catch ex As Exception 

      End Try 
     End Using 

Dalla mia ricerca oggi è suona come se questo è fondamentalmente male, ma lo SqlCommand non viene smaltito.

Domanda -> Quale dei seguenti esempi è il modo migliore per affrontare questo?

Esempio 2 - Eliminare manualmente

 Using cn As New SqlConnection(ConnectionString) 
      Try 
       Dim cmd As SqlCommand = New SqlCommand 
       With cmd 
        .Connection = cn 
        .Connection.Open() 
        .CommandText = "dbo.GetCustomerByID" 
        .CommandType = CommandType.StoredProcedure 
        .Parameters.Add("@CustomerID", SqlDbType.Int, 4) 
        .Parameters("@CustomerID").Value = CustomerID 
       End With 

       da = New SqlDataAdapter(cmd) 
       cmd.Dispose() 
       da.Fill(ds, "Customer") 
      Catch ex As Exception 

      End Try 
     End Using 

Esempio 3 - smaltimento automatico con la privacy Usando

 Using cn As New SqlConnection(ConnectionString) 
      Try 
       Using cmd As New SqlCommand 
        With cmd 
         .Connection = cn 
         .Connection.Open() 
         .CommandText = "dbo.GetCustomerByID" 
         .CommandType = CommandType.StoredProcedure 
         .Parameters.Add("@CustomerID", SqlDbType.Int, 4) 
         .Parameters("@CustomerID").Value = CustomerID 
        End With 

        da = New SqlDataAdapter(cmd) 
        da.Fill(ds, "Customer") 
       End Using 
      Catch ex As Exception 

      End Try 
     End Using 

Esempio 4 - Lo stesso di esempio 3 ma il try/catch è all'interno della Usando - Questo fa la differenza?

 Using cn As New SqlConnection(ConnectionString) 
      Using cmd As New SqlCommand 
       Try 
        With cmd 
         .Connection = cn 
         .Connection.Open() 
         .CommandText = "dbo.GetCustomerByID" 
         .CommandType = CommandType.StoredProcedure 
         .Parameters.Add("@CustomerID", SqlDbType.Int, 4) 
         .Parameters("@CustomerID").Value = CustomerID 
        End With 

        da = New SqlDataAdapter(cmd) 
        da.Fill(ds, "Customer") 
       Catch ex As Exception 

       End Try 
      End Using 
     End Using 

Esempio 5 - Lo stesso di esempio 4 ma il CommandText e cn sono specificati nella Dichiarazione Usando - Che vantaggio ha questo?

 Using cn As New SqlConnection(ConnectionString) 
      Using cmd As New SqlCommand("GetCustomerByID", cn) 
       Try 
        With cmd 
         .Connection.Open() 
         .CommandType = CommandType.StoredProcedure 
         .Parameters.Add("@CustomerID", SqlDbType.Int, 4) 
         .Parameters("@CustomerID").Value = CustomerID 
        End With 

        da = New SqlDataAdapter(cmd) 
        da.Fill(ds, "Customer") 
       Catch ex As Exception 

       End Try 
      End Using 
     End Using 

Esempio 6 - Lo stesso come nell'esempio 5, ma la connessione è aperta su cn anziché cmd. È meglio aprire la connessione su cmd se deve essere eseguita solo una stored procedure?

 Using cn As New SqlConnection(ConnectionString) 
      cn.Open() 

      Using cmd As New SqlCommand("GetCustomerByID", cn) 
       Try 
        With cmd 
         .Connection = cn 
         .CommandType = CommandType.StoredProcedure 
         .Parameters.Add("@CustomerID", SqlDbType.Int, 4) 
         .Parameters("@CustomerID").Value = CustomerID 
        End With 

        da = New SqlDataAdapter(cmd) 
        da.Fill(ds, "Customer") 
       Catch ex As Exception 

       End Try 
      End Using 
     End Using 
+1

L'istruzione using è più sicura, ma un try/catch che ignora tutte le eccezioni è scoraggiato nella maggior parte delle situazioni. Quindi, come e dove mettere il tuo tentativo, tutto dipende da quello che stai cercando di realizzare. Qual'è la tua domanda? –

+0

questa domanda mi sembra più adatta a codereview.stackexchange.com –

+0

Il try/catch vuoto era solo un esempio, ma in questo caso era solo lì per sicurezza. Esterno alla procedura in cui stavo per verificare se il set di dati conteneva tabelle. Se così non fosse, mi occuperei in modo appropriato. Per quanto riguarda la domanda, era al top - stavo chiedendo qual è il modo migliore per gestire lo smaltimento di SqlCommand. Personalmente ritengo che l'Esempio 5 sia quello giusto ma volevo sapere il feedback degli altri. –

risposta

7

Il comando DataAdapter.Fill si apre e chiude la connessione stessa, in modo da non è necessario il cmd.Connection.Open(). (Rif: sezione commenti in http://msdn.microsoft.com/en-us/library/377a8x4t.aspx.)

L'utilizzo di Using per SqlConnection ha l'effetto di chiamare .Close su di esso.

La variabile cmd diventa idonea per la garbage collection una volta fuori ambito (o precedente se .NET determina che non verrà più utilizzato).

Nell'esempio 2, non sono sicuro che sia una buona idea eliminare il cmd prima che DataAdapter lo abbia usato.

+0

Grazie. Non lo sapevo riguardo gli adattatori di dati, quindi modificheremo di conseguenza. Quindi se l'elemento diventa eleggibile per la garbage collection stai dicendo che l'istruzione Using non è veramente necessaria? –

+0

@cw_dev Sì. Una cosa che mi ha morso è sulla falsariga di 'Using cmd ... cmd.Connection = ... cmd.Connection.Open() ... (esegui e leggi) ... End Using' che non chiude la connessione all'interno del cmd. Tuttavia, non sembra che lo farai. Usare 'Using' su un SqlConnection è un metodo conveniente per farlo. Chiudere() la connessione per te. –