Dans la base de données la ligne est supprimée, mais une Exception
On touche à un comportement classique d’Entity Framework : même si la ligne est supprimée physiquement dans la base, le contexte EF garde en mémoire l’état des entités. Si une entité a été modifiée dans le contexte (EntityState.Modified
) mais que sa ligne n’existe plus en base, EF va lever une exception de concurrence ou de mise à jour lors de SaveChanges()
.
Pourquoi ça se produit
-
Tu as une entité suivie par le contexte (
DbContext
) :var entity = context.MyEntities.Find(id); entity.SomeProp = "new value";
→ EF marque cette entité comme Modified.
-
Puis la ligne correspondante est supprimée directement en base (par SQL ou par un autre contexte/processus).
-
Quand tu appelles
context.SaveChanges()
, EF tente de faire unUPDATE
.
→ Mais la ligne n’existe plus → conflit, exception levée.-
L’
InnerException
montre l’entité Modified.
-
Comment résoudre le problème
1️⃣ Vérifier l’état de l’entité avant SaveChanges()
var entry = context.Entry(entity);
Console.WriteLine(entry.State); // Modified, Deleted, Added, Unchanged
Si la ligne a disparu, tu peux changer l’état :
entry.State = EntityState.Detached; // ignore l'entité dans SaveChanges
ou
entry.State = EntityState.Unchanged; // ne tente pas de la mettre à jour
2️⃣ Gérer les suppressions concurrentes (optimistic concurrency)
Si plusieurs processus peuvent supprimer ou modifier la même ligne :
try
{
context.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
foreach (var entry in ex.Entries)
{
// Décider quoi faire : detacher ou recharger
entry.State = EntityState.Detached;
}
}
3️⃣ S’assurer que tu ne modifies pas une entité déjà supprimée
-
Avant de modifier, fais un check si l’entité existe :
var entity = context.MyEntities.Find(id);
if (entity != null)
{
entity.SomeProp = "new value";
}
-
Ou utilise
AsNoTracking()
si tu veux juste lire sans que le contexte suive les changements.
💡 En résumé : l’exception survient parce qu’EF tente de mettre à jour une entité qui n’existe plus en base.
-
Soit tu détaches cette entité avant
SaveChanges()
-
Soit tu gères la concurrence avec
DbUpdateConcurrencyException
.