He "heredado" un poco el método C# que crea un objeto ADO.NET SqlCommand y bucles sobre una lista de temas que se guarda en la base de datos (SQL Server 2005).Refactoring ADO.NET - SqlTransaction vs TransactionScope
En este momento, se utiliza el enfoque tradicional SqlConnection/SqlCommand, y para asegurarse de que todo funciona, los dos pasos (eliminar entradas antiguas, luego insertar nuevas) se envuelven en una SqlTransaction de ADO.NET.
using (SqlConnection _con = new SqlConnection(_connectionString))
{
using (SqlTransaction _tran = _con.BeginTransaction())
{
try
{
SqlCommand _deleteOld = new SqlCommand(......., _con);
_deleteOld.Transaction = _tran;
_deleteOld.Parameters.AddWithValue("@ID", 5);
_con.Open();
_deleteOld.ExecuteNonQuery();
SqlCommand _insertCmd = new SqlCommand(......, _con);
_insertCmd.Transaction = _tran;
// add parameters to _insertCmd
foreach (Item item in listOfItem)
{
_insertCmd.ExecuteNonQuery();
}
_tran.Commit();
_con.Close();
}
catch (Exception ex)
{
// log exception
_tran.Rollback();
throw;
}
}
}
Ahora, he estado leyendo mucho sobre la clase de .NET TransactionScope últimamente, y me preguntaba, ¿cuál es el enfoque preferido aquí? Iba a ganar nada (legibilidad, velocidad, fiabilidad) por el cambio a utilizar
using (TransactionScope _scope = new TransactionScope())
{
using (SqlConnection _con = new SqlConnection(_connectionString))
{
....
}
_scope.Complete();
}
Lo que usted prefiere, y por qué?
Marc
De acuerdo, gracias John - y sí, tienes razón - este ejemplo no tiene SqlCommand en el uso de() bloques (todavía!) - esto es trabajo en progreso :-) –
re: SQLCommand dentro de usar, ¿hay alguna otra razón, además de la recolección de basura, por ejemplo: Dispose() para un SQLConnection llama al método Close(), ¿así que Dispose() llama a cualquier método SQLCommand? –
Si una clase implementa 'IDisposable', y si crea una instancia de esta clase, debe llamar a Dispose en ella. La forma más sencilla de hacerlo es con un bloque 'using'. Encuentro que es mejor acostumbrarme a implementar uno. –