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


Respuestas:


275

En general, no es correcto que pueda " eliminar un elemento de una base de datos " con ambos métodos. Para ser precisos, es así:

  • ObjectContext.DeleteObject(entity)marca la entidad comoDeleted en el contexto. (Es EntityStatees Deleteddespués de eso.) Si llama SaveChangesdespués EF envía un SQL DELETEdeclaración a la base de datos. Si no se violan las restricciones referenciales en la base de datos, la entidad se eliminará; de lo contrario, se generará una excepción.

  • EntityCollection.Remove(childEntity)marca la relación entre padre y childEntitycomoDeleted . Si el childEntitymismo se elimina de la base de datos y lo que sucede exactamente cuando llama SaveChangesdepende del tipo de relación entre los dos:

    • Si la relación es opcional , es decir, la clave externa que hace referencia del elemento secundario al elemento primario en la base de datos permite NULLvalores, este elemento externo se establecerá en nulo y si llama a SaveChangeseste NULLvalor childEntity, se escribirá en la base de datos (es decir, la relación entre los dos se eliminan). Esto sucede con una UPDATEdeclaración SQL . No se DELETEproduce ninguna declaración.

    • Si se requiere la relación (el FK no permite NULLvalores) y la relación no se identifica (lo que significa que la clave externa no es parte de la clave primaria (compuesta) del niño), debe agregar el niño a otro padre o tienes que eliminar explícitamente el hijo (con DeleteObjectentonces). Si no lo hace cualquiera de estos una restricción de referencia es violada y EF será una excepción cuando se llama SaveChanges- el infame " La relación no podía ser cambiado debido a una o más de las propiedades de clave externa es no anulable " excepción o similar.

    • Si la relación se identifica (está necesariamente requiere a continuación, ya que cualquier parte de la clave primaria no puede ser NULL) EF marcará el childEntitytan Deletedasí. Si llama , se enviará SaveChangesuna DELETEdeclaración SQL a la base de datos. Si no se violan otras restricciones referenciales en la base de datos, la entidad se eliminará; de lo contrario, se generará una excepción.

De hecho, estoy un poco confundido acerca de la sección de Comentarios en la página de MSDN que ha vinculado porque dice: " Si la relación tiene una restricción de integridad referencial, llamar al método Remove en un objeto dependiente marca tanto la relación como el objeto dependiente para su eliminación. ". Esto me parece poco preciso o incluso incorrecto porque los tres casos anteriores tienen una " restricción de integridad referencial ", pero solo en el último caso el niño es de hecho eliminado. (A menos que signifiquen con " objeto dependiente " un objeto que participa en una relación de identificación, lo que sería una terminología inusual).


2
Wikipedia de integridad referencial: la integridad referencial es una propiedad de los datos que, cuando se satisface, requiere que cada valor de un atributo (columna) de una relación (tabla) exista como un valor de otro atributo en una relación (tabla) diferente (o la misma) ), por lo que cuando la relación es Opcional, rompemos la regla de Integridad de datos
Mohammadreza

3
@Mohammadreza: Si interpreta NULLcomo "No es un valor" (en lugar de "el valor NULL" como escribí a veces un poco descuidado), una "relación opcional" no está en contradicción con esa definición de integridad referencial.
Slauma

1
Entonces, ¿cuál es la versión EF Core ObjectContext.DeleteObject?
Jonathan Allen el

13

Si realmente desea usar Suprimido, tendría que hacer que sus claves foráneas se anularan, pero luego terminaría con registros huérfanos (que es una de las razones principales por las que no debería estar haciendo eso en primer lugar). Así que solo usaRemove()

ObjectContext.DeleteObject (entidad) marca la entidad como eliminada en el contexto. (Su EntityState se elimina después de eso). Si llama a SaveChanges después, EF envía una declaración DELETE de SQL a la base de datos. Si no se violan las restricciones referenciales en la base de datos, la entidad se eliminará; de lo contrario, se generará una excepción.

EntityCollection.Remove (childEntity) marca la relación entre parent e childEntity como Deleted. Si childEntity se elimina de la base de datos y lo que sucede exactamente cuando llama a SaveChanges depende del tipo de relación entre los dos:

Una cosa que vale la pena señalar es que la configuración .State = EntityState.Deleted no activa el cambio detectado automáticamente. ( archivo )


44
Ok, para aquellos que votaron negativamente por mi respuesta, no tiene nada que ver con Slauma: ambos apuntan a la misma documentación . El mío explica ejemplos de la vida real, mientras que su teoría forma parte de él.
Matas Vaitkevicius el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.