EF: Comment dois-je appeler SaveChanges deux fois à l'intérieur d'une transaction?
À l'aide de Entity Framework (le premier code dans mon cas), j'ai une opération qui m'oblige à appeler SaveChanges pour mettre à jour un objet dans la base de données, puis SaveChanges nouveau pour mettre à jour un autre objet. (J'ai besoin de la première SaveChanges pour résoudre un problème où les EF ne pouvez pas comprendre quel est l'objet à mettre à jour en premier).
J'ai essayé de faire:
using (var transaction = new TransactionScope())
{
// Do something
db.SaveChanges();
// Do something else
db.SaveChanges();
tramsaction.Complete();
}
Quand je le lance, j'obtiens une exception à la deuxième SaveChanges
appel, en disant: "le fournisseur sous-jacent a échoué à l'ouverture". L'exception interne dit que MSDTC n'est pas activé sur ma machine.
Maintenant, j'ai vu des posts d'ailleurs qui décrivent comment activer ms DTC, mais il me semble que j'aurais également besoin de permettre l'accès au réseau, etc. Cela sonne comme complète exagéré ici, car il n'y a pas d'autres bases de données concernées, sans parler d'autres serveurs. Je ne veux pas faire quelque chose qui va rendre ma requête dans son ensemble est moins sûr (ou plus lent).
Il doit sûrement y avoir un plus léger façon de le faire (idéalement sans MSDTC)?!
Si vous voulez tout faire en une seule transaction, quelle est la différence entre l'épargne tout en une fois, ou de tout enregistrer plusieurs Fois? Dans les deux cas, tout sera sauvé ou rien ne sera enregistré, donc je ne vois pas l'avantage de multiples arrêts. Comme par le commentaire ci-dessous - dans Sql Server 2005 l'ouverture d'une connexion multiple au sein d'une transaction (même si la source est la même) provoque la promotion de la transaction une transaction distribuée. Ce qui a été amélioré dans Sql Server 2008, où vous pouvez ouvrir plusieurs connexions à la même source de données à l'intérieur d'un trx sans causer de promotion
Je suis à l'aide de SQL server 2012. Je n'ai pas (ou ne veulent) les connexions multiples, et ne veulent pas vraiment à l'utilisation de MSDTC!
Je ne comprends pas. J'ai pensé que chaque SaveChanges serait d'utiliser sa propre transaction, et donc, la première peut réussir, et le second pourrait échouer et revenir, laissant ma base de données incohérentes. C'est pourquoi j'ai pensé que j'avais besoin d'une transaction externe. Avais-je tort?
Si il y a une ambiance de transaction de votre connexion sera automatiquement inscrit dans cette transaction et SavaChanges ne va pas créer une nouvelle transaction. En outre, les transactions imbriquées ne sont pas vraiment pris en charge sur SqlServer (c'est à dire imbriquée Begin Tran sont ignorés)
OriginalL'auteur Gary McGill | 2012-10-09
Vous devez vous connecter pour publier un commentaire.
Il est probablement causée par deux connexions différentes utilisées dans votre transaction. Essayez de contrôler la connexion de votre opération manuellement:
OriginalL'auteur Ladislav Mrnka
Je sais que c'est le genre de réponse tardive mais j'ai trouvé utile de partager.
Maintenant dans EF6 il est plus facile de acheeve en utilisant
dbContext.Database.BeginTransaction()
comme ceci :
pour plus d'informations regardez cette
de nouveau, c'est dans EF6 à Partir de
Vous êtes les bienvenus 🙂
Vous devriez en faire plus avec le bloc catch que juste de restauration et d'avaler de l'exception. Journal, renvoyer, ...
Est le
try/catch
bloc-elle nécessaire? Ne pas leusing
prendre soin de la manipulation de l'exception? (quelque chose comme l'appel deRollback
dans la méthode dispose dedbContextTransaction
)Je ne suis pas sûr à 100% mais comme je sais disposer lui-même ne vais pas faire une restauration.
OriginalL'auteur Wahid Bitar
En appelant SaveChanges() comme vous êtes cause que les données soient conservées dans la base de données et l'EF oublier sur les changements qu'il vient de faire.
L'astuce est d'utiliser SaveChanges(faux), de sorte que les modifications sont conservées dans la DB, mais EF n'oubliez pas les changements qu'il apporte donc de faire des enregistrement /de réessayer possible.
P. S. dès Que vous avez plus d'une connexion à l'intérieur transactionscope il VA remonter à la DTC.
Que faire si la première opération de mise à jour se passe bien, mais la deuxième opération de mise à jour échoue, vos données sont dans la base de données cohérente?
Depuis le tout est enveloppé dans TransactionScope, puis-je l'espère bien!
En effet, ce que je voulais dire, c'est que l'utilisation de SaveChanges(faux) alors on met à jour la base de données, il laissera le contexte est, de sorte qu'il est plus facile de déterminer ce qui / où la fonction s'est mal passé, et réessayer si vous le souhaitez.
OriginalL'auteur Paul Zahra
Pour la réponse finale sélectionnée ci-dessus, il y a une faute de frappe. Corrigé ligne ci-dessous:
Aussi, besoin d'ajouter des références pour le Système.Les données.De l'entité.De l'Infrastructure et du Système.Les Transactions
OriginalL'auteur MJDConsultingGroup