2013-01-17 13 views
6

Sto codificando una transazione manualmente in ADO.NET. L'esempio di cui sto lavorando riutilizza lo SqlCommand che sembra un'ottima idea.Devo chiamare Parameters.Clear quando riutilizzi un SqlCommand con una transazione?

Tuttavia, ho aggiunto i parametri al mio comando.

La mia domanda è: nel codice seguente, è command.Parameters.Clear() corretta? O sto sbagliando?

using (var connection = new SqlConnection(EomAppCommon.EomAppSettings.ConnStr)) 
{ 
    connection.Open(); 
    SqlTransaction transaction = connection.BeginTransaction(); 
    SqlCommand command = connection.CreateCommand(); 
    command.Transaction = transaction; 
    try 
    { 
     foreach (var itemIDs in this.SelectedItemIds) 
     { 
      command.CommandText = "UPDATE Item SET payment_method_id = @batchID WHERE id in (@itemIDs)"; 
      // IS THE FOLLOWING CORRECT? 
      command.Parameters.Clear(); 

      command.Parameters.Add(new SqlParameter("@batchID", batchID)); 
      command.Parameters.Add(new SqlParameter("@itemIDs", itemIDs)); 
      command.ExecuteNonQuery(); 
     } 
     transaction.Commit(); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("Failed to update payment batches, rolling back." + ex.Message); 
     try 
     { 
      transaction.Rollback(); 
     } 
     catch (Exception exRollback) 
     { 
      if (!(exRollback is InvalidOperationException)) // connection closed or transaction already rolled back on the server. 
      { 
       MessageBox.Show("Failed to roll back. " + exRollback.Message); 
      } 
     } 
    } 
} 
+0

Perché non creare semplicemente il comando all'interno del ciclo? O creare un'istruzione SQL in grado di eseguire tutti gli aggiornamenti in una volta sola ed evitare completamente il ciclo? –

risposta

6

Dal momento che si sta eseguendo più volte la stessa query, è necessario eliminarli - è possibile aggiungere i parametri al di fuori del ciclo e solo riempirli dentro.

try 
{ 
    command.CommandText = "UPDATE Item SET payment_method_id = @batchID WHERE id in (@itemIDs)"; 
    command.Parameters.Add(new SqlParameter("@batchID", 0)); 
    command.Parameters.Add(new SqlParameter("@itemIDs", "")); 

    foreach (var itemIDs in this.SelectedItemIds) 
    { 
     command.Parameters["@batchID"].Value = batchID; 
     command.Parameters["@itemIDs"].Value = itemIDs; 
     command.ExecuteNonQuery(); 
    } 
    transaction.Commit(); 
} 

Nota - you can't use parameters with IN as you've got here - non funzionerà.

+0

sì, ho appena scoperto che riguardo alla clausola IN, grazie per il link –

1

In questa condizione è necessario in quanto è necessario impostare nuovi valori dei parametri, quindi è corretto.

A proposito, spostare

command.CommandText = ".." 

al di fuori del ciclo anche, come non è mai cambiato.

+0

grazie per il consiglio di spostare la linea fuori dal loop –

Problemi correlati