Je voudrais exécuter plusieurs instructions d'insertion sur plusieurs tables. J'utilise dapper.net. Je ne vois aucun moyen de gérer les transactions avec dapper.net.
S'il vous plaît partagez vos idées sur la façon d'utiliser les transactions avec dapper.net.
Voici l'extrait de code:
using System.Transactions;
....
using (var transactionScope = new TransactionScope())
{
DoYourDapperWork();
transactionScope.Complete();
}
Notez que vous devez ajouter une référence à System.Transactions
Assembly car il n'est pas référencé par défaut.
J'ai préféré utiliser une approche plus intuitive en obtenant la transaction directement à partir de la connexion:
// This called method will get a connection, and open it if it's not yet open.
using (var connection = GetOpenConnection())
using (var transaction = connection.BeginTransaction())
{
connection.Execute(
"INSERT INTO data(Foo, Bar) values (@Foo, @Bar);", listOf5000Items, transaction);
transaction.Commit();
}
Vous devriez pouvoir utiliser TransactionScope
puisque Dapper n’exécute que les commandes ADO.NET.
using (var scope = new TransactionScope())
{
// insert
// insert
scope.Complete();
}
Étant donné que toutes vos tables sont dans une seule base de données, je ne suis pas d’accord avec la solution TransactionScope
proposée dans certaines réponses ici. Reportez-vous à this answer.
TransactionScope
est généralement utilisé pour les transactions distribuées; Une transaction couvrant différentes bases de données peut se trouver sur un système différent. Cela nécessite des configurations sur le système d'exploitation et SQL Server sans lesquelles cela ne fonctionnerait pas. Ceci n'est pas recommandé si toutes vos requêtes concernent une seule instance de base de données.
Cependant, avec une base de données unique, cela peut être utile lorsque vous devez inclure le code dans une transaction qui n'est pas sous votre contrôle. Avec une base de données unique, il n’a pas non plus besoin de configurations spéciales.
connection.BeginTransaction
Est la syntaxe ADO.NET pour implémenter une transaction (en C #, VB.NET, etc.) avec une base de données unique. Cela ne fonctionne pas sur plusieurs bases de données.
Donc, connection.BeginTransaction()
est la meilleure solution.
Même le meilleur moyen de gérer la transaction consiste à implémenter UnitOfWork comme expliqué dans la réponse this .
La réponse de Daniel a fonctionné comme prévu pour moi. Pour être complet, voici un extrait qui illustre la validation et l'annulation à l'aide d'une portée de transaction et d'un dapper:
using System.Transactions;
// _sqlConnection has been opened elsewhere in preceeding code
using (var transactionScope = new TransactionScope())
{
try
{
long result = _sqlConnection.ExecuteScalar<long>(sqlString, new {Param1 = 1, Param2 = "string"});
transactionScope.Complete();
}
catch (Exception exception)
{
// Logger initialized elsewhere in code
_logger.Error(exception, $"Error encountered whilst executing SQL: {sqlString}, Message: {exception.Message}")
// re-throw to let the caller know
throw;
}
} // This is where Dispose is called