Entity Framework DbContext.Remove (obj) vs .Entry (obj) .State = EntityState.Deleted

First I use EF Code. simple model:

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); } 

when deleting an object using Delete () , it will delete the element and its associated child elements (object image records).

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

but when mark it to remove:

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

get error:

The operation failed: the relation cannot be changed because one or more properties of the foreign key are not NULL. When a change in relationship occurs, the corresponding property of the foreign key is set to zero. If the foreign key does not support null values, a new relationship must be defined, another nonzero value must be assigned to the foreign key property, or an object not associated with it must be deleted.

+7
c # entity-framework
source share
1 answer

If you really want to use Deleted, you will have to make your foreign keys nullified, but then you will end up in orphaned entries (which is one of the main reasons why you should not do this in the first place). So just use Remove()

ObjectContext.DeleteObject (entity) marks an object as deleted in context. (After that, the EntityState is deleted.) If you call SaveChanges after that, EF sends the SQL DELETE statement to the database. If no reference restrictions in the database are violated, the object will be deleted, otherwise an exception will be thrown.

EntityCollection.Remove (childEntity) marks the relationship between parent and childEntity as Deleted. If childEntity itself is deleted from the database, and what exactly happens when SaveChanges is called, depends on the type of relationship between the two:

If the relation is optional, that is, the foreign key that refers from the child to the parent in the database is nullable, this foreigner will be null, and if you call SaveChanges, this NULL value for childEntity will be written to the database (i.e. e. communication between two remote). This happens with the SQL UPDATE statement. The DELETE statement is not executed.

If a relationship is required (FK does not allow NULL values) and the relationship is not identified (which means that the foreign key is not part of the main (child) child key), you need to either add the child to another parent or you must explicitly delete the child ( then using DeleteObject). If you do not perform any of these actions, the link restriction will be violated, and EF will throw an exception when you call SaveChanges - the notorious one. β€œThe relationship cannot be changed because one or more exceptions to the foreign key are excluded” or similar.

If the relationship is identified (it is necessarily required because any part of the primary key cannot be NULL), EF will also mark the child as deleted. If you call SaveChanges, the SQL DELETE statement will be sent to the database. If no other reference restrictions in the database are violated, the object will be deleted, otherwise an exception will be thrown.

It should be noted that setting .State = EntityState.Deleted does not cause an automatically detected change.

+14
source share

All Articles