133 votes

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 pas de moyen de gérer les transactions avec dapper.net.

Veuillez partager vos idées sur la manière d'utiliser les transactions avec dapper.net.

118voto

the_joric Points 4755

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 car il n'est pas référencé par défaut.

7 votes

Est-il nécessaire d'effectuer un retour en arrière explicite en cas d'erreur ou System.Transactions s'en charge-t-il automatiquement ?

6 votes

@NorbertNorbertson il le fait automatiquement, en Dispose() méthode. Si Complete() n'a pas été appelé, la transaction est annulée.

5 votes

Il convient de le mentionner en raison d'une autre réponse ( stackoverflow.com/a/20047975/47672 ) : la connexion doit être ouverte à l'intérieur de TransctionScope en utilisant le bloc au cas où vous choisissez cette réponse.

114voto

ANeves Points 2711

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

0 votes

@ANeves : Eh bien, nous utilisons probablement des cadres différents de Dapper, parce que celui-ci a : github.com/StackExchange/dapper-dot-net

33 votes

Il faut appeler connection.open() avant .begintransaction

1 votes

Une connexion n'est pas automatiquement enrôlée dans TransactionScope à moins que vous n'ouvriez la connexion dans TransactionScope. Je ne sais pas comment votre code fonctionne, si GetOpenConnection s'ouvre par magie dans le transactioncope, mais je parie qu'il ne le fait pas.

20voto

Daniel A. White Points 91889

Vous devriez être en mesure d'utiliser TransactionScope puisque Dapper n'exécute que des commandes ADO.NET.

using (var scope = new TransactionScope())
{
   // open connection
   // insert
   // insert
   scope.Complete();
}

11voto

Amit Joshi Points 5007

Considérant que toutes vos tables sont dans une seule base de données, je ne suis pas d'accord avec TransactionScope solution suggérée dans certaines réponses ici. Voir ce réponse.

  1. TransactionScope est généralement utilisé pour les transactions distribuées ; les transactions couvrant différentes bases de données peuvent se trouver sur différents systèmes. Cela nécessite certaines configurations du système d'exploitation et du serveur SQL, sans lesquelles cela ne fonctionnera pas. Cette méthode n'est pas recommandée si toutes vos requêtes portent sur une seule instance de la base de données.
    Mais, 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 ne nécessite pas non plus de configurations spéciales.

  2. connection.BeginTransaction est une syntaxe ADO.NET permettant de mettre en œuvre une transaction (en C#, VB.NET, etc.) dans une seule base de données. Cela ne fonctionne pas avec plusieurs bases de données.

Donc, connection.BeginTransaction() est le meilleur moyen d'y arriver.

La meilleure façon de gérer la transaction est d'implémenter UnitOfWork, comme expliqué dans le document suivant ce réponse.

10voto

Sanity1123 Points 505

Il y a 3 approches pour effectuer des transactions dans Dapper.

  1. Transaction simple
  2. Transaction de la portée de la transaction
  3. Utilisation de Dapper Transaction ( paquet nuget supplémentaire et l'approche la plus privilégiée )

Vous pouvez en savoir plus sur ces méthodes de transaction sur le site officiel du tutoriel. ici

Pour référence, voici une ventilation des approches de la transaction

1. Transaction simple

Dans cet exemple, vous créez une transaction sur une connexion db existante, puis vous passez la transaction à la méthode Execute sur dapper (qui est un paramètre facultatif).

Une fois que vous avez fait tout votre travail, il suffit de valider la transaction.

string sql = "INSERT INTO Customers (CustomerName) Values (@CustomerName);";

using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
    connection.Open();

    using (var transaction = connection.BeginTransaction())
    {
        connection.Execute(sql, new {CustomerName = "Mark"}, transaction: transaction);
        connection.Execute(sql, new {CustomerName = "Sam"}, transaction: transaction);
        connection.Execute(sql, new {CustomerName = "John"}, transaction: transaction);

        transaction.Commit();
    }
}

2. Transaction du périmètre de la transaction

Si vous souhaitez créer une portée de transaction, vous devrez le faire avant la création de la connexion à la base de données. Une fois que vous avez créé l'étendue de la transaction, vous pouvez simplement effectuer toutes vos opérations et ensuite faire un appel unique pour terminer la transaction, qui validera alors toutes les commandes.

using (var transaction = new TransactionScope())
{
    var sql = "INSERT INTO Customers (CustomerName) Values (@CustomerName);";

    using (var connection = My.ConnectionFactory())
    {
        connection.Open();

        connection.Execute(sql, new {CustomerName = "Mark"});
        connection.Execute(sql, new {CustomerName = "Sam"});
        connection.Execute(sql, new {CustomerName = "John"});
    }

    transaction.Complete();
}

3. Utilisation de la transaction Dapper

C'est l'approche la plus favorable pour réaliser une transaction dans le code, car elle rend le code facile à lire et à mettre en œuvre. Il existe une implémentation étendue de SQL Transaction appelée Dapper Transaction (que vous pouvez trouver à l'adresse suivante ici ), qui vous permet d'exécuter directement les exécutions SQL des transactions.

string sql = "INSERT INTO Customers (CustomerName) Values (@CustomerName);";

using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
    connection.Open();

    using (var transaction = connection.BeginTransaction())
    {
        transaction.Execute(sql, new {CustomerName = "Mark"});
        transaction.Execute(sql, new {CustomerName = "Sam"});
        transaction.Execute(sql, new {CustomerName = "John"});

        transaction.Commit();
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X