3 votes

Erreur lors de l'enregistrement de l'ObjectContext après avoir remplacé l'élément parent et y avoir lié l'élément enfant

Dans mon application, l'interface permet à l'utilisateur de créer et de supprimer des entités dans un modèle Entity Framework. Toutes les modifications sont ajoutées au fichier ObjectContext et n'est sauvegardé que lorsque l'utilisateur sélectionne "Sauvegarder".

La meilleure façon de poser ma question est d'utiliser l'exemple simple suivant :

J'ai une relation de clé étrangère entre deux types d'entités, que j'appellerai Parent y Child ici. La base de données, en SQLite, est déclarée comme suit :

CREATE TABLE Parents   (ID INTEGER PRIMARY KEY);

CREATE TABLE Children  
(
    ID INTEGER PRIMARY KEY,
    ParentID INTEGER NOT NULL 
        CONSTRAINT FK_ChildrenToParents REFERENCES [Parents](ID) 
            ON DELETE CASCADE ON UPDATE CASCADE
)

Je construis ensuite un modèle Entity Framework sur cette base de données et j'exécute les actions suivantes (voir le code ci-dessous) :

  1. Créer un Parent
  2. Économiser
  3. Supprimer le Parent
  4. Créer un nouveau Parent avec le même numéro d'identification que l'original
  5. Créer un Child et lui fournir le nouveau Parent Numéro d'identification de la personne
  6. Sauvegarder (échoue)

    demoDBEntities entities = new demoDBEntities();

    Parent originalParent = new Parent { ID = 1 }; entities.Parents.AddObject(originalParent);

    entities.SaveChanges(); // First Save

    entities.Parents.DeleteObject(originalParent);

    Parent newParent = new Parent { ID = 1 }; entities.Parents.AddObject(newParent); Child newChild = new Child { ID = 2, ParentID = 1 }; entities.Children.AddObject(newChild);

    entities.SaveChanges(); // Second Save

J'obtiens l'erreur suivante lors du deuxième appel à SaveChanges() :

"Unable to insert or update an entity because the principal end of the 'demoDBModel.FK_Children_0_0' relationship is deleted."

Il semble que le problème vienne du fait que l'Entity Framework lie le nouveau Child à l'article originalParent qui est ensuite supprimée et remplacée par l'élément newParent article. Cela peut paraître prétentieux, mais c'est tout à fait naturel dans mon application.

Existe-t-il un moyen de contourner ce problème ?

PS : je sais qu'il est déconseillé de réutiliser les numéros d'identification des entrées de la base de données - cependant, dans mon cas, les numéros d'identification sont des numéros d'actifs, qui peuvent théoriquement être réutilisés. Cela dit, le scénario ci-dessus se produit généralement lorsque le client crée un fichier Parent puis le supprime, le recrée et crée le fichier Child article.

3voto

Slauma Points 76561

Au lieu de définir la propriété de la clé étrangère ParentID vous pourriez essayer de définir l'une des propriétés de navigation (vous devez en avoir au moins une) et n'utiliser qu'un seul appel à AddObject pour ajouter le graphe d'objets complet au contexte :

Soit :

//...
entities.Parents.DeleteObject(originalParent);

Child newChild = new Child { ID = 2 };
Parent newParent = new Parent { ID = 1, Children = new List<Child>{ newChild } };
entities.Parents.AddObject(newParent);

entities.SaveChanges();

Ou bien :

//...
entities.Parents.DeleteObject(originalParent);

Parent newParent = new Parent { ID = 1 };
Child newChild = new Child { ID = 2, Parent = newParent };
entities.Children.AddObject(newChild);

entities.SaveChanges();

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