Cadre d'entité insérant dans 3 tables la bonne manière et restauration en cas d'exception
-
20-12-2019 - |
Question
J'ai une question très simple et je me demande comment la faire EXACTEMENT correctement.UTILISER LE CADRE D'ENTITÉ ET ESSAYER AUSSI LE MODÈLE DE DÉPÔT MAINTENANTJ'ai 3 tableaux :
Story id PRIMARY KEY IDENTITY
Album id PRIMARY KEY IDENTITY
Photo id PRIMARY KEY IDENTITY
Je veux INSÉRER une nouvelle histoire comme celle-ci :
_db.Repository.Insert(oneStory);
Save(); // Save will save it to table story
oneStory.id; // return id of last added row.
Ensuite, en utilisant l'identifiant de l'histoire récemment ajoutée, je souhaite enregistrer un album comme celui-ci
oneAlbum.fk_storyid=oneStory.id
_db.Repository.Insert(oneAlbum);
Save(); // Save will save it to table album
oneAlbum.id; // return id of last added row.
Ensuite, en utilisant l'identifiant de l'album récemment ajouté, je souhaite enregistrer une photo comme celle-ci
onePhoto.fk_albumid=oneAlbum.id
_db.Repository.Insert(onePhoto);
Save(); // Save will save it to table photo
onePhoto.id; // return id of last added row.
Voici le problème
- Que se passe-t-il si lors de l'enregistrement d'un album ou d'une photo, une exception se produit, l'histoire est déjà ajoutée, peut-être que l'album est également ajouté, comment restaurer et supprimer cette histoire ou ces modifications ?
- -Grande question : pouvons-nous obtenir l'identifiant de la ligne récemment ajoutée sans Save() et en utilisant simplement insert ?De cette façon, je peux faire toutes les insertions et également continuer à obtenir un identifiant, puis enregistrer à la fin comme UNITÉ DE TRAVAIL.
Alors, quelqu'un peut-il me guider ici, comment c'est fait PARFAIT, ce qui permettra d'économiser du temps, moins de code et également une bonne structure.Merci.
La solution
Dans le cadre d'entité, le DbContext
lui-même est à la fois un dépôt et un unité de travail.
Si vous souhaitez créer des référentiels supplémentaires en plus de cela, vous devez injecter le DbContext
en eux afin que toutes les opérations utilisent le même DbContext
et tu appelles seulement SaveChanges
une fois.
Dans ce cas, vous devez utiliser les propriétés de navigation pour lier les objets entre eux au lieu de la clé étrangère - puisque vous n'avez pas encore de valeurs de clé.EF insérera automatiquement les éléments dans le bon ordre et attribuera des valeurs aux clés étrangères.
Si ce n'est pas une option, vous pouvez utiliser un TransactionScope
pour tout envelopper en une seule transaction :
using(var tx = new TransactionScope())
{
_db.Repository.Insert(oneStory);
Save(); // Save will save it to table story
oneStory.id; // return id of last added row.
_db.Repository.Insert(oneStory);
Save(); // Save will save it to table story
oneStory.id; // return id of last added row.
onePhoto.fk_albumid=oneAlbum.id
_db.Repository.Insert(onePhoto);
Save(); // Save will save it to table photo
onePhoto.id; // return id of last added row.
tx.Complete();
}