web-dev-qa-db-fra.com

Comment utiliser les transactions avec dapper.net?

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.

96
Amit

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.

93
the_joric

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();
}
87
ANeves

Vous devriez pouvoir utiliser TransactionScope puisque Dapper n’exécute que les commandes ADO.NET.

using (var scope = new TransactionScope())
{
   // insert
   // insert
   scope.Complete();
}
18
Daniel A. White

É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.

  1. 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.

  2. 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 .

6
Amit Joshi

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 
4
Sudhanshu Mishra