Child collection not saved in Entity Framework Core

Viewed 722

We are able to save changes to a parent object but changes to the children collection are not persisted.

We have used naming conventions that allow EF Core to discover the relationship and build the db correctly.

The example I am testing has a parent with a single child entity in the db. We have added a second child entity to the MyChildren collection of that parent. Why is it that SaveChanges does not persist the update to the MyChildren collection to the db?

public class ParentType
{
    public Guid ParentId { get; set; }
    public string SomeString { get; set; }
    public ObservableCollection<ChildType> MyChildren { get; set; } = new ObservableCollection<ChildType>();
}

public class ChildType
{
    public Guid Child { get; set; }
    public ParentType MyParent { get; set; }
}
// in the example parentIn is passed with 2 ChildType entities in MyChildren.
public static ParentType SaveMe(ParentType parentIn)
{
    ParentType parentSaved = null;
    using (DataContext db = new DataContext())
    {
        if (parentIn.ParentId == Guid.Empty)
        {
            parentSaved = new ParentType();
            parentSaved.ParentId = Guid.NewGuid();
            db.Parents.Add(parentSaved);
        }
        else
        {
        // in the example parentIn is found in the db with 1 child entity
            parentSaved = db.Parents.Where(e => e.ParentId == parentIn.ParentId).Include(e => e.MyChildren).SingleOrDefault();
        }
        parentSaved.SomeString = parentIn.SomeString;
        parentSaved.MyChildren = parentIn.MyChildren;

        int result = db.SaveChanges();
        return parentSaved;
    }
}

SomeString is saved, but MyChildren are not. There is no error. Why are the child entities not updated?

EDIT 1 As a workaround I have removed the children collection from the db before adding the new children collection.

else
    {
    // in the example parentIn is found in the db with 1 child entity
        parentSaved = db.Parents.Where(e => e.ParentId == parentIn.ParentId).Include(e => e.MyChildren).SingleOrDefault();
        db.Parents.RemoveRange(parentSaved.MyChildren);
        db.SaveChanges();
    }
    parentSaved.SomeString = parentIn.SomeString;
    parentSaved.MyChildren = parentIn.MyChildren;

    int result = db.SaveChanges();
    return parentSaved;

This works but is unsatisfatory as saving a Parent is no longer transactional. Is there a better way?

0 Answers
Related