Entity Framework.Remove() vs.DeleteObject()
vous pouvez supprimer un élément d'une base de données en utilisant EF en utilisant les deux méthodes suivantes.
le premier est sur le EntityCollection
et le second sur le ObjectContext
.
utilisé?
est-ce que l'un est préféré à l'autre?
Remove()
retourne bool
et DeleteObject()
retourne void
.
2 réponses
il n'est généralement pas correct que vous pouvez " 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 estEntityState
estDeleted
après cela.) Si vous appelezSaveChanges
après EF envoie une instruction SQLDELETE
à la base de données. Si aucune contrainte de référence dans le l'entité sera supprimée, sinon une exception est lancée. -
EntityCollection.Remove(childEntity)
marques la relation entre parent etchildEntity
commeDeleted
. Si lechildEntity
lui - même est supprimé de la base de données et ce qui se passe exactement quand vous appelezSaveChanges
dépend du type de relation entre les deux:-
si la relation est optionnel , c'est-à-dire que la clé étrangère qui renvoie de l'enfant au parent dans la base de données permet des valeurs
NULL
, cet étranger sera défini à null et si vous appelezSaveChanges
cette valeurNULL
pour lechildEntity
sera écrite dans la base de données (c'est-à-dire que la relation entre les deux est supprimée). Cela se produit avec une déclaration SQLUPDATE
. Il n'y a pas de mentionDELETE
. -
si la la relation est obligatoire (la FK ne permet pas les valeurs
NULL
) et la relation est n'identifiant 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 ou vous devez supprimer explicitement l'enfant (avecDeleteObject
alors). Si vous ne faites rien de tout cela, une contrainte référentielle est violée et EF fera une exception lorsque vous appelezSaveChanges
- l'infâme " la relation ne pouvait pas être changée parce qu'une ou plusieurs des propriétés de la clé étrangère est non-nullable exception ou similaire. -
si la relation est identifiant (c'est nécessairement requis alors parce qu'aucune partie de la clé primaire ne peut être
NULL
) EF marquera lechildEntity
commeDeleted
aussi. Si vous appelezSaveChanges
une instruction SQLDELETE
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 lancée.
-
je suis en fait un peu confus au sujet de la section remarques sur la page MSDN vous avez lié parce qu'il dit: " si la relation a une intégrité référentielle contrainte, appelant la méthode Remove sur un objet dépendant marque à la fois la relation et l'objet dépendant pour la suppression. ". Cela me semble imprécis ou même erroné parce que les trois cas ci-dessus ont un " 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 la terminologie.)
si vous voulez vraiment utiliser Deleted, vous devez rendre vos clés étrangères nulles, mais alors vous finirez avec les dossiers orphelins (ce qui est l'une des principales raisons pour lesquelles vous ne devriez pas faire cela en premier lieu). Il suffit donc d'utiliser Remove()
ObjectContext.DeleteObject (entity) marque l'entité telle que supprimée dans le contexte. (C'est EntityState est Supprimé par la suite.) Si vous appelez SaveChanges après EF envoie une déclaration SQL DELETE à la 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 lancée.
EntityCollection.Remove (childEntity) marque la relation entre le parent et l'enfant telle que supprimée. Si l'identité enfantine elle-même est supprimée de la base de données et ce qui se passe exactement quand vous appelez SaveChanges dépend du type de relation entre les deux:
Une chose à noter est que le réglage .State = EntityState.Deleted
ne déclenche pas automatiquement le changement détecté. ( archive )