2014-07-15 11 views
7

Per prima cosa sto usando il codice EF. un modello semplice:Entity Framework DbContext .Remove (obj) vs .Entry (obj) .State = EntityState.Deleted

item { public int Id {set; get;},... ,ICollection<ItemImages> {set; get;} } 

    itemImages { 
     public int Id {set; get; }, 
     public int ItemId {set; get; } 
      , ... , 
     public Item Item {set; get; } 
     } 

ItemConfig:EntityTypeConfiguration<Item> 
{ 
//some config statement; 
//... 
// mark child delete when parent delete: waterfall delete. 
HasRequired(rs => rs.ItemCat).WithMany(rs => rs.Items).HasForeignKey(rs => rs.ItemCatId).WillCascadeOnDelete(true); 
} 

quando un'entità di eliminazione da Remove(), esso Cancellare e figli correlate (le immagini degli elementi record) bene.

_db.Item.Remove(DeleteThisObj); 
_db.SaveChanges(); 

ma quando Mark è da eliminare: l'errore

_db.Entry(DeleteThisObj).State = EntityState.Deleted; 
_db.SaveChanges(); 

get:

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

+0

Eventuali duplicati di [Entity Framework .Rimuovere() vs. .DeleteObject()] (http://stackoverflow.com/questions/17723626/entity-framework- remove-vs-deleteobject) –

risposta

14

Se davvero si vuole utilizzare eliminata, è avrebbe dovuto fare le vostre chiavi esterne annullabile, ma poi si finirebbe con i record orfani (che è uno dei motivi principali per cui non dovresti farlo in primo luogo). Quindi usa solo Remove()

ObjectContext.DeleteObject(entity) contrassegna l'entità come eliminata nel contesto. (Dopo questo viene eliminato EntityState.) Se si chiama SaveChanges, EF invia un'istruzione SQL DELETE al database. Se non vengono violati i 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 il childEntity stesso viene eliminato dal database e ciò che accade esattamente quando si chiama SaveChanges dipende dal tipo di relazione tra i due:

Se la relazione è facoltativa, vale a dire la chiave esterna che fa riferimento dal figlio al genitore in il database consente i valori NULL, questo straniero verrà impostato su null e se si chiama SaveChanges questo valore NULL per il childEntity verrà scritto nel database (ovvero la relazione tra i due viene rimossa). Questo succede con un'istruzione SQL UPDATE. Non si verifica alcuna istruzione DELETE.

Se la relazione è richiesta (l'FK non consente valori NULL) e la relazione non è identificativa (il che significa che la chiave esterna non fa parte della chiave primaria del figlio (composito)) è necessario aggiungere figlio a un altro genitore o devi eliminare esplicitamente il figlio (con DeleteObject quindi). Se non si esegue alcuna di queste operazioni, un vincolo referenziale viene violato e EF genera un'eccezione quando si chiama SaveChanges - l'infame "La relazione non può essere modificata perché una o più proprietà della chiave esterna non sono annullabili" o simili.

Se la relazione si sta identificando (è necessariamente necessaria in quanto qualsiasi parte della chiave primaria non può essere NULL) EF segnerà anche childEntity come Deleted. Se si chiama SaveChanges, un'istruzione SQL DELETE verrà inviata al database. Se non vengono violati altri vincoli referenziali nel database, l'entità verrà eliminata, altrimenti verrà generata un'eccezione.

Una cosa da notare è che l'impostazione .State = EntityState.Deleteddoes not trigger automatically detected change.

+0

così Remove() contrassegna i record di stato childs nel contesto come Deleted ma Entry (obj) .state = EntityStae.Deleted no? voglio che cada l'acqua caduta – Mohammadreza

+1

@Mohammadreza Si può pensare in questo modo, "Rimuovi" influenza la registrazione e le relazioni mentre "cancella" influenza solo il record a portata di mano. –

Problemi correlati