When working with OwnsMany and removing items from a collection, the EF ChangeTracker gets into an invalid status. It still HasChanges() == true after completion of SaveChanges().
While investigating this, and diving into the mongo-efcore-provider repository, I found that this issue is somewhat mentioned, although I believe the root cause is not an empty collection as stated there:
https://github.com/mongodb/mongo-efcore-provider/blob/main/tests/MongoDB.EntityFrameworkCore.FunctionalTests/Query/OwnedEntityTests.cs#L682
The problem is that after a SaveChanges(), there are still pending changes, due to keys that changed.
The current numeric ID assignments conflict with the pre-save status, causing corrupted state. (cannot modify value of a readonly key)
System.InvalidOperationException : The property 'Location.Id' is defined as read-only after it has been saved, but its value has been modified or marked as modified. Sta
In this test, just trying to do a SaveChanges again, will blow up. So it's not related to the collection going empty.
I think the status of HasChanges() of changetracker should always be false, after a SaveChanges()
{
using var db = SingleEntityDbContext.Create(collection);
var found = db.Entities.Single();
Assert.Equal(2, found.locations.Count);
found.locations.RemoveAt(0);
db.SaveChanges();
Assert.Single(found.locations, l => l.longitude == 4.4m);
bool hasChanges = db.ChangeTracker.HasChanges(); <!-- this is still true
db.SaveChanges(); // <!-- just calling this, will already throw
I tried to work around this, by manually assigning a key.
This however also has several caviats.
- Adding a key will also introduce a FK of the parent into the owned entity, which doesn't make sense in a document DB.
- It tries to add an index on it (auto index on FK convention)
- Trying to ignore the ownerId (as seen in code, setting HasElementName("") to empty, results in an invalid index name.
- Disabling the convention for FK creation does by-pass this (maybe this convention should also not be active on Owned entities?
- The auto defined key is (OwnerId, Id), but I even when having a trustwurthy Id on that entity myself, I can't adjust this pre-defined key. That results in Id doesn't exist in the document exceptions
The things I tried to solve it, are all just overcoming the incorrect post SaveChanges() ChangeTracker status. That to me seems the root cause, which in tests was also encountered, but considered a problem of removing last item from a collection.