0

I'm building and MVC project using Entity-Framework 6 (code first).

My database Data Models (code first):

public class ParentNode
{
   public int ParentNodeId { get; set; }

   public string SomeParentData { get; set; }

   //FK
   [Required] 
   public int ChildNodeId { get; set; }
   public virtual ChildNode ChildNode { get; set; }
}


public class ChildNode
{
   public int ChildNodeId { get; set; }

   public string SomeChildishData { get; set; }

   //References to this table/model
   public virtual ICollection<ParentNode> ParentNodes{ get; set; }
}

The issue: Deleting multiple ChildNodes

  • I won't rely on cascade delete
  • ParentNode->ChildNode has a many to one relation. In case I need to delete one ChildNode, I first delete the ParentNode then the ChildNode ()
  • Deleting just one ChildNode will be done like this:

Deleting one ChildNode: no problem (if only 1 is present in the list)

Deleting multiple ChildNodes: FK Null reference error occurs

{
 ...
 foreach(ParentNode parentToDelete in parentNodeList)
 {
   db.Entry(parentToDelete).State = EntityState.Deleted;
   db.SaveChanges();     
 }

 foreach(ChildNode childToDelete in childNodeList)
 {
   db.Entry(childToDelete).State = EntityState.Deleted;
   db.SaveChanges();   //Error Exception occurs here!!
 }
 ...
}

error message:

An exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll but was not handled in user code

Additional information: 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.

enter image description here


Table rows state when error occurred

Parent

PK: RestaurantMenuCategoryId

FK: restaurantMenuNameId

enter image description here

Child

PK: restaurantMenuNameId

enter image description here


As you can see parent table still has a reference to child row restaurantMenuNameId == 2, whilst the expected behaviour is that parent reference should have been deleted before accessing the child table.

My observations:

  • By looking at the database, it seems that when db.SaveChanges() occurs for the parent node, even though the DELETE query in the database hasn't occurred, the code keeps on moving asynchronously. Synchronous behaviour should be used, instead of a fire and forget?
  • An other possibility is that DbContext isn't updated after the parent delete, this could have been true if by looking at the db the parent rows were deleted but they were "still there". So what is going on?

Question: Please let me know what the problem is, what are the main topics that are related to this issue?

Carlo Luther
  • 2,402
  • 7
  • 46
  • 75
  • 'cause yer deletin' parents, not chitdrens. – Keith Payne Jul 05 '15 at 16:52
  • Can you please explain the tables, what are the primary keys and what are foreign keys here? – Lasse V. Karlsen Jul 05 '15 at 16:54
  • you are backwards, you have to delete all the child nodes first, then delete the parent when there aren't any more child nodes left. – Claies Jul 05 '15 at 16:57
  • @Claies I think that the OP has simply mixed up the two names in the example code. In fact, the children are parents and the parents are children. – Keith Payne Jul 05 '15 at 17:01
  • @Lasse V. Karlsen (Parent: PK: RestaurantMenuCategoryId FK: restaurantMenuNameId), (Child: PK: restaurantMenuNameId) – Carlo Luther Jul 05 '15 at 17:01
  • I recommend posting the real models, perhaps with all the non-key attributes removed. If you're investigating something that ought to work but doesn't, the answer is usually found in your code, not a bug in EF. – Keith Payne Jul 05 '15 at 17:03
  • @KeithPayne no, I don't think so, the screenshot of the code shows marking the parent `RestaurantMenuCategory` for deletion, then trying to mark the child `RestaurantMenuName` for deletion. It even is labelled that way in the comments for "Steps". The steps are in the wrong order. – Claies Jul 05 '15 at 17:05
  • I'm not looking for a cascade delete, hence I don't want to delete the child first and then cascade delete the parent. I'm doing it manually. I'll first delete the parents with the (FK), once the child entities are orphans I'll delete them. Simple as that. – Carlo Luther Jul 05 '15 at 17:06
  • but you *can't* do it that way, because your database doesn't allow the children to be orphans. – Claies Jul 05 '15 at 17:07
  • @Claies Yes the screen shot is of the actual code, the variable names are different from the example I posted, I did it for simplicity. But the algorithm in the example I posted is identical to the real one. – Carlo Luther Jul 05 '15 at 17:08
  • @Claies Children can be orphans, I've tested this with just one single row delete of a parent and child. The problem is when you delete multiple rows, it acts as the call is async. ie database is still deleting the parent and the code deleting the child fires before the confirmation that the parent has been deleted. – Carlo Luther Jul 05 '15 at 17:12
  • If the issue was that childs can't be orphans this doesn't explain the error message: The relationship could not be changed because one or more of the foreign-key properties is "non-nullable" – Carlo Luther Jul 05 '15 at 17:16
  • Perhaps this http://stackoverflow.com/a/5543559/2516770 is occurring? – Keith Payne Jul 05 '15 at 20:22

0 Answers0