Entity Framework. Remover () vs. .DeleteObject ()

Puede eliminar un elemento de una base de datos usando EF utilizando los dos métodos siguientes.

El primero está en EntityCollection y el segundo en ObjectContext .

¿Cuándo se debe usar cada uno?

¿Se prefiere uno sobre el otro?

Remove() devuelve un bool y DeleteObject() devuelve void .

Generalmente no es correcto que pueda ” eliminar un elemento de una base de datos ” con ambos métodos. Para ser preciso, es así:

  • ObjectContext.DeleteObject(entity) marca la entidad como Deleted en el contexto. (Se EntityState después). Si llama a SaveChanges después, EF envía una statement SQL DELETE a la base de datos. Si no se infringen las restricciones referenciales en la base de datos, se eliminará la entidad; de lo contrario, se lanzará una excepción.

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

    • Si la relación es opcional , es decir, la clave externa que hace referencia desde el hijo al padre en la base de datos permite valores NULL , este valor externo se establecerá en nulo y si llama a SaveChanges este valor NULL para childEntity se escribirá en la base de datos ( es decir, se elimina la relación entre los dos). Esto sucede con una instrucción SQL UPDATE . No se produce statement DELETE .

    • Si la relación es necesaria (el FK no permite valores NULL ) y la relación no identifica (lo que significa que la clave externa no es parte de la clave primaria (compuesta) del niño) tiene que agregar el niño a otro padre o tiene que eliminar explícitamente el hijo (con DeleteObject entonces). Si no hace ninguno de estos, se viola una restricción referencial y EF lanzará una excepción cuando llame a SaveChanges : la infame ” La relación no se pudo cambiar porque una o más de las propiedades de clave externa no son nulables “. o similar.

    • Si la relación se identifica (se requiere necesariamente porque cualquier parte de la clave principal no puede ser NULL ) EF marcará childEntity como Deleted también. Si llama a SaveChanges se SaveChanges una statement SQL DELETE a la base de datos. Si no se infringen otras restricciones referenciales en la base de datos, la entidad será eliminada, de lo contrario se lanzará una excepción.

De hecho, estoy un poco confundido acerca de la sección 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 Eliminar en un objeto dependiente marca la relación y el objeto dependiente para su eliminación. “. Esto parece impreciso o incluso incorrecto para mí 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 que sería una terminología inusual).

Si realmente quieres usar Eliminado, tendrías que hacer que tus claves foráneas sean nulables, pero luego terminarías con registros huérfanos (que es una de las principales razones por las que no deberías hacer eso en primer lugar). Así que solo use Remove()

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

EntityCollection.Remove (childEntity) marca la relación entre parent y childEntity como eliminada. Si el childEntity mismo se elimina de la base de datos y lo que ocurre exactamente cuando llamas a SaveChanges depende del tipo de relación entre los dos:

Una cosa digna de mención es que establecer .State = EntityState.Deleted no desencadena el cambio detectado automáticamente. ( archivo )