Collection of children is not saved in Entity Framework Core

We can save changes to the parent, but changes to the collection of children are not saved.

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

The example I am testing has a parent with only one child in the db. We have added a second child to this parent's MyChildren collection. Why is SaveChanges not saving the update of 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 persists, but MyChildren does not. There are no errors. Why haven't the child objects been updated?

EDIT 1 . As a workaround, I removed the child collection from the db before adding the new 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 unsatisfactory since the parent save is no longer transactional. Is there a better way?

+3


source to share





All Articles