Quand vous avez un code comme celui-ci :
Something something = new Something();
BlahEntities b = new BlahEntities()
b.AddToSomethingSet(something);
b.SaveChanges();
comment exécuter cet ajout à l'intérieur d'une transaction ?
Quand vous avez un code comme celui-ci :
Something something = new Something();
BlahEntities b = new BlahEntities()
b.AddToSomethingSet(something);
b.SaveChanges();
comment exécuter cet ajout à l'intérieur d'une transaction ?
L'ObjectContext possède une propriété de connexion que vous pouvez utiliser pour gérer les transactions.
using (var context = new BlahEntities())
using (var tx = context.BeginTransaction())
{
// do db stuff here...
tx.Commit();
}
En cas d'exception, la transaction sera annulée. Étant donné que l'appel à BeginTransaction() nécessite une connexion ouverte, il est logique d'envelopper l'appel à BeginTransaction éventuellement dans une méthode d'extension.
public static DbTransaction BeginTransaction(this ObjectContext context)
{
if (context.Connection.State != ConnectionState.Open)
{
context.Connection.Open();
}
return context.Connection.BeginTransaction();
}
Un scénario dans lequel je pense que cette approche pourrait être utile par rapport au TransactionScope, c'est lorsque vous devez accéder à deux sources de données et que vous avez seulement besoin d'un contrôle transactionnel sur une des connexions. Je pense que dans ce cas, le TransactionScope fera la promotion d'une transaction distribuée qui ne sera peut-être pas nécessaire.
Vous pouvez placer votre code à l'intérieur d'une portée de transaction.
using(TransactionScope scope = new TransactionScope())
{
// Your code
scope.Complete(); // To commit.
}
TransactionScope se trouve dans l'espace de noms System.Transactions qui est situé dans l'assemblage du même nom (que vous devrez peut-être ajouter manuellement à votre projet).
Je sais que pour LINQ to SQL, le contexte de données créera une transaction pour SubmitChanges() s'il n'y a pas de transaction ambiante existante (TransactionScope est une transaction "ambiante"). Je n'ai pas vu cela documenté pour LINQ to Entities, mais j'ai vu un comportement qui suggère que c'est vrai pour Entity Framework également.
Ainsi, tant que vous utilisez un seul SubmitChanges() (L2SQL) ou SaveChanges() (Linq to Entities) pour toutes les modifications liées, vous devriez pouvoir vous passer de TransactionScope. Vous avez besoin d'un TransactionScope lorsque
J'ai eu des problèmes avec les TransactionScopes imbriqués. Elles sont censées fonctionner, et les cas de test simples fonctionnent, mais lorsque j'entre dans le code de production, la transaction "interne" semble être le même objet que la transaction externe. Les symptômes incluent des erreurs qui sont soit "la transaction s'est engagée, vous ne pouvez plus utiliser cette transaction", soit "cet objet de transaction a déjà été éliminé". Les erreurs se produisent dans la transaction externe après que la transaction interne a effectué son travail.
using System.Transactions;
using (TransactionScope scope = new TransactionScope())
{
try
{
using(DataContext contextObject = new DataContext(ConnectionString))
{
contextObject.Connection.Open();
// First SaveChange method.
contextObject.SaveChanges();
// Second SaveChange method.
contextObject.SaveChanges();
//--continue to nth save changes
// If all execution successful
scope.Complete();
}
}
catch(Exception ex)
{
// If any exception is caught, roll back the entire transaction and end the scope.
scope.Dispose();
}
finally
{
// Close the opened connection
if (contextObject.Connection.State == ConnectionState.Open)
{
contextObject.Connection.Close();
}
}
}
Trouvez le lien ci-dessous pour une explication détaillée https://msdn.microsoft.com/en-us/data/dn456843.aspx
Dans toutes les versions d'Entity Framework, chaque fois que vous exécutez SaveChanges() pour insérer, mettre à jour ou supprimer dans la base de données, le framework englobe cette opération dans une transaction. Cette transaction ne dure que le temps d'exécuter l'opération et se termine ensuite. Lorsque vous exécutez une autre opération de ce type, une nouvelle transaction est lancée. Pour la dernière version d'Entity Framework : 6.0 +
Lire la suite ici : EntityFramework et Transaction
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.