Entity Framework .Remove () ou .DeleteObject ()


141

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

Le premier est sur le EntityCollectionet le second sur le ObjectContext.

Quand faut-il utiliser chacun d'eux?

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

Remove()renvoie a boolet DeleteObject()retourne void.

Réponses:


275

Il 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é commeDeleted dans le contexte. (Il est EntityStateest Deletedaprès.) Si vous appelez SaveChangesaprès EF envoie une SQL DELETEdéclaration à 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 childEntityasDeleted . Si le childEntitylui-même est supprimé de la base de données et que ce qui se passe exactement lorsque vous appelez SaveChangesdé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 de l'enfant au parent dans la base de données autorise les NULLvaleurs, cette étrangère sera mise à null et si vous appelez SaveChangescette NULLvaleur pour le childEntitysera écrit dans la base de données (c'est-à-dire la relation entre les deux sont supprimés). Cela se produit avec une UPDATEinstruction SQL . Aucune DELETEdéclaration ne se produit.

    • Si la relation est requise (le FK n'autorise pas les NULLvaleurs) et que la relation ne s'identifie pas (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 vous devez supprimer explicitement l'enfant (avec DeleteObjectalors). Si vous n'effectuez aucune de ces opérations, une contrainte référentielle est violée et EF lèvera une exception lorsque vous appelez SaveChanges- la tristement célèbre exception " La relation n'a pas pu être modifiée car une ou plusieurs des propriétés de clé étrangère ne peuvent pas être nulles " ou similaire.

    • Si la relation est d' identifier (il est nécessairement requis alors que toute partie de la clé primaire ne peut pas être NULL) EF marquera le childEntitycomme Deletedainsi. Si vous appelez SaveChangesune DELETEinstruction SQL 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 la section Remarques sur la page MSDN que vous avez liée car elle dit: « Si la relation a une contrainte d'intégrité référentielle, l'appel de 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 ou même faux car les trois cas ci-dessus ont une " contrainte d'intégrité référentielle " mais seulement dans le dernier cas, 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 une terminologie inhabituelle.)


2
L'intégrité référentielle wikipedia: L'intégrité référentielle est une propriété de données qui, lorsqu'elle est satisfaite, exige que chaque valeur d'un attribut (colonne) d'une relation (table) existe en tant que valeur d'un autre attribut dans une relation différente (ou la même) (table ), donc lorsque la relation est facultative, nous enfreignons la règle d'intégrité des données
Mohammadreza

3
@Mohammadreza: Si vous interprétez NULLcomme "Pas une valeur" (au lieu de "la valeur NULL" comme je l'écrivais parfois un peu bâclé) alors une "relation optionnelle" n'est pas en contradiction avec cette définition de l'intégrité référentielle.
Slauma

1
Alors, quelle est la version EF Core ObjectContext.DeleteObject?
Jonathan Allen

13

Si vous voulez vraiment utiliser Supprimé, vous devez rendre vos clés étrangères nullables, mais vous vous retrouverez alors avec des enregistrements orphelins (ce qui est l'une des principales raisons pour lesquelles vous ne devriez pas faire cela en premier lieu). Alors utilisez simplementRemove()

ObjectContext.DeleteObject (entité) marque l'entité comme supprimée dans le contexte. (C'est EntityState est supprimé après cela.) Si vous appelez SaveChanges par la suite, 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 le childEntity lui-même 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:

Il convient de noter que le réglage .State = EntityState.Deleted ne déclenche pas de changement détecté automatiquement. ( archives )


4
Ok, pour ceux qui votent contre ma réponse, cela n'a rien à voir avec celle de Slauma - ils pointent tous les deux vers la même documentation . Le mien explique des exemples réels alors que sa théorie en fait partie.
Matas Vaitkevicius
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.