web-dev-qa-db-fra.com

Entity Framework .Remove () vs. .DeleteObject ()

Vous pouvez supprimer un élément d'une base de données à l'aide de EF en utilisant les deux méthodes suivantes.

Le premier est sur le EntityCollection et le second sur le ObjectContext.

Quand faut-il utiliser chacun?

L'un est-il préféré à l'autre?

Remove() renvoie un bool et DeleteObject() renvoie void.

137
Sam Leach

Ce n’est généralement pas correct que vous puissiez "supprimer un élément d’une base de données" avec les deux méthodes. Pour être précis c'est comme ça:

  • ObjectContext.DeleteObject(entity) marque l'entité sous la forme Deleted dans le contexte. (C'est EntityState c'est Deleted après.) Si vous appelez SaveChanges après, EF envoie une instruction SQL DELETE à la base de données. Si aucune contrainte référentielle dans la base de données n'est violée, l'entité sera supprimée, sinon une exception est levée.

  • EntityCollection.Remove(childEntity) marque la relation entre le parent et childEntity comme Deleted. Si le childEntity lui-même est supprimé de la base de données et ce qui se passe exactement lorsque vous appelez SaveChanges dépend du type de relation entre les deux:

    • Si la relation est facultative , c'est-à-dire que la clé étrangère qui fait référence à l'enfant du parent dans la base de données autorise NULL valeurs, cette volonté étrangère être défini sur null et si vous appelez SaveChanges cette NULL valeur pour le childEntity sera écrite dans la base de données (la relation entre les deux est supprimée). Cela se produit avec une instruction SQL UPDATE. Aucune instruction DELETE ne se produit.

    • Si la relation est obligatoire (le FK n'autorise pas les valeurs NULL) et que la relation est non identifiant (ce qui signifie que la clé étrangère ne fait pas partie de la clé primaire (composite) de l'enfant), vous devez soit ajouter l'enfant à un autre parent, soit le supprimer explicitement (avec DeleteObject alors). Si vous ne le faites pas, une contrainte référentielle est violée et EF lève une exception lorsque vous appelez SaveChanges - l’infâme " la relation n’a pas pu être modifiée car un ou plusieurs des propriétés de clé étrangère est non nullable " exception ou similaire.

    • Si la relation identifie (il est nécessairement obligatoire , car toute partie de la clé primaire ne peut pas être NULL) EF marquera également childEntity comme Deleted. Si vous appelez SaveChanges, une instruction SQL DELETE sera envoyée à la base de données. Si aucune autre contrainte référentielle dans la base de données n'est violée, l'entité sera supprimée, sinon une exception est levée.

Je suis en fait un peu confus au sujet de section Remarques de la page MSDN vous l'avez liée car elle indique: "Si la relation a une contrainte d'intégrité référentielle, appelez la méthode Remove sur un objet dépendant marque à la fois la relation et l'objet dépendant pour suppression. ". Cela me semble imprécis, voire erroné, car les trois cas ci-dessus ont un "contrainte d'intégrité référentielle", mais ce n'est que dans le dernier cas que l'enfant est en fait supprimé. (À moins qu'ils ne signifient avec "objet dépendant" un objet qui participe à une relation d'identification qui serait cependant une terminologie inhabituelle.)

269
Slauma

Si vous voulez vraiment utiliser Supprimé, vous devez rendre vos clés étrangères nullables, mais vous vous retrouvez avec des enregistrements orphelins (une des principales raisons pour lesquelles vous ne devriez pas le faire en premier lieu). Il suffit donc d'utiliser Remove()

ObjectContext.DeleteObject (entity) marque l'entité comme supprimée dans le contexte. (C'est ensuite que EntityState est supprimé.) Si vous appelez ensuite SaveChanges, EF envoie une instruction SQL DELETE à la base de données. Si aucune contrainte référentielle dans la base de données n'est violée, l'entité sera supprimée, sinon une exception est levée.

EntityCollection.Remove (childEntity) marque la relation entre parent et childEntity comme supprimée. Si childEntity est supprimé de la base de données et que ce qui se passe exactement lorsque vous appelez SaveChanges dépend du type de relation entre les deux:

Une chose à noter est que le paramètre .State = EntityState.Deletedne déclenche pas automatiquement le changement détecté. ( archive )

13
Matas Vaitkevicius