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


Risposte:


275

Non è generalmente corretto che è possibile " rimuovere un elemento da un database " con entrambi i metodi. Per essere precisi è così:

  • ObjectContext.DeleteObject(entity)contrassegna l'entità comeDeleted nel contesto. (E ' EntityStateè Deleteddopo.) Se si chiama SaveChangesdopo EF invia una SQL DELETEdichiarazione alla banca dati. Se non vengono violati vincoli referenziali nel database, l'entità verrà eliminata, altrimenti verrà generata un'eccezione.

  • EntityCollection.Remove(childEntity)segna la relazione tra parent e childEntityasDeleted . Se lo childEntitystesso viene eliminato dal database e cosa succede esattamente quando si chiama SaveChangesdipende dal tipo di relazione tra i due:

    • Se la relazione è facoltativa , ovvero la chiave esterna che fa riferimento dal figlio al genitore nel database consente NULLvalori, questo estero verrà impostato su null e se si chiama SaveChangesquesto NULLvalore per childEntityverrà scritto nel database (ovvero la relazione tra i due vengono rimossi). Questo succede con UPDATEun'istruzione SQL . Non si DELETEverifica alcuna affermazione.

    • Se è richiesta la relazione (l'FK non consente i NULLvalori) e la relazione non sta identificando (il che significa che la chiave esterna non fa parte della chiave primaria (composita) del figlio) è necessario aggiungere il figlio a un altro genitore o devi eliminare esplicitamente il figlio (con DeleteObjectallora). Se non si esegue alcuna di queste, viene violato un vincolo referenziale e EF genererà un'eccezione quando si chiama SaveChanges: la famigerata " La relazione non può essere modificata perché una o più proprietà della chiave esterna non sono nulla " eccezione o simile.

    • Se il rapporto è identificare (è necessariamente richiesto allora perché ogni parte della chiave primaria non può essere NULL) EF segnerà il childEntitycome Deletedpure. Se si chiama un'istruzione SaveChangesSQL DELETEverrà inviata al database. Se non vengono violati altri vincoli referenziali nel database, l'entità verrà eliminata, altrimenti verrà generata un'eccezione.

In realtà sono un po 'confuso riguardo alla sezione Note sulla pagina MSDN che hai collegato perché dice: " Se la relazione ha un vincolo di integrità referenziale, la chiamata del metodo Remove su un oggetto dipendente contrassegna sia la relazione che l'oggetto dipendente per la cancellazione. ". Questo mi sembra impreciso o addirittura sbagliato perché tutti e tre i casi precedenti hanno un " vincolo di integrità referenziale ", ma solo nell'ultimo caso il bambino viene effettivamente eliminato. (A meno che non intendano con " oggetto dipendente " un oggetto che partecipa a una relazione identificativa che sarebbe comunque una terminologia insolita.)


2
Integrità referenziale wikipedia: L'integrità referenziale è una proprietà dei dati che, se soddisfatta, richiede che ogni valore di un attributo (colonna) di una relazione (tabella) esista come valore di un altro attributo in una relazione diversa (o uguale) (tabella ), quindi quando la relazione è facoltativa infrangiamo la regola di integrità dei dati
Mohammadreza,

3
@Mohammadreza: Se interpreti NULL"Non un valore" (anziché "il valore NULL" come ho scritto a volte un po 'sciatto), una "relazione facoltativa" non è in contraddizione con quella definizione di integrità referenziale.
Slauma,

1
Allora, qual è la versione EF Core di ObjectContext.DeleteObject?
Jonathan Allen,

13

Se vuoi davvero usare Cancella, dovresti rendere nulla le tue chiavi esterne, ma poi finiresti con i record orfani (che è uno dei motivi principali per cui non dovresti farlo in primo luogo). Quindi basta usareRemove()

ObjectContext.DeleteObject (entity) contrassegna l'entità come eliminata nel contesto. (Successivamente EntityState viene eliminato.) Se in seguito si chiama SaveChanges, EF invia un'istruzione SQL DELETE al database. Se non vengono violati vincoli referenziali nel database, l'entità verrà eliminata, altrimenti verrà generata un'eccezione.

EntityCollection.Remove (childEntity) contrassegna la relazione tra parent e childEntity come eliminata. Se childEntity stesso viene eliminato dal database e cosa succede esattamente quando si chiama SaveChanges dipende dal tipo di relazione tra i due:

Una cosa degna di nota è che l'impostazione .State = EntityState.Deleted non attiva il cambiamento rilevato automaticamente. ( archivio )


4
Ok, per coloro che votano in negativo la mia risposta non ha nulla a che fare con quella di Slauma: entrambi indicano la stessa documentazione . Il mio spiega esempi di vita reale mentre la sua teoria ne fa parte.
Matas Vaitkevicius,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.