Say you have these classes in your entities.
public class Parent { public int ParentID { get; set; } public virtual ICollection<Child> Children { get; set; } } public class Child { public int ChildID { get; set; } public int ParentID { get; set; } public virtual Parent Parent { get; set; } }
And you have a user interface for updating Parent along with its Children , that is, if the user adds a new Child , then you need to insert, if the user is editing an existing Child , then you need an update, and if the user removes Child , then you need to delete. Now, obviously, if you use the following code
public void Update(Parent obj) { _parent.Attach(obj); _dbContext.Entry(obj).State = EntityState.Modified; _dbContext.SaveChanges(); }
he will not be able to detect changes inside the Child , because EF cannot detect changes inside the navigation property.
I asked this question 4 times and got mixed answers. So is it even possible to do this without complication? This problem can fix the problem by dividing the user interface between Parent and Child , but I don’t want to, because merging both Child and Parent in one menu is quite common in developing business applications and is more user-friendly.
UPDATE: I am trying to find a solution below, but it does not work.
public ActionResult(ParentViewModel model) { var parentFromDB = context.Parent.Get(model.ParentID); if (parentFromDB != null) { parentFromDB.Childs = model.Childs; } context.SaveChanges(); }
Instead of detecting changes within children, EF will not be able to tell what to do with the old child. For example, if parentFromDB has 3 children, then the first time I pull it out of the database, I delete the 2nd and 3rd children. Then I get The relationship could not be changed because one or more of the foreign-key properties is non-nullable when saved.
I believe this happened: Relations cannot be changed because one or more properties of the foreign key cannot be reset
Which took me back to the square, because in my script I can’t just extract from the database and update the record and call SaveChanges .