Skip to content

Comments

EF-293: Fix entity states for owned entity collections#281

Merged
damieng merged 4 commits intomongodb:mainfrom
damieng:ef-293
Feb 23, 2026
Merged

EF-293: Fix entity states for owned entity collections#281
damieng merged 4 commits intomongodb:mainfrom
damieng:ef-293

Conversation

@damieng
Copy link
Collaborator

@damieng damieng commented Feb 18, 2026

Fixes EF-293 which reported owned entities were causing an exception if saved more than once after some types of modification to the collection.

There were three issue involved in this:

Issue 1: Promoted root entities

When only an owned entity changes (e.g. removing a collection item), the root document is Unchanged from EF's perspective. Our GetAllChangedRootEntries promotes it to Modified for writing, but EF's AcceptAllChanges only processes its original entries list with the root staying permanently Modified.

Fix: Add promoted roots to EF's entries list so AcceptAllChanges processes them. This matches how the EF Cosmos provider handles the same scenario in (CosmosDatabaseWrapper.cs:76-82).

Issue 2: Ordinal key marking

SetStoreGeneratedValue on ordinal key properties used the default overload which set the modified as true, which could mark owned entity entries as Modified even though they were Unchanged before save.

Fix: Pass setModified: false, matching the intent already expressed in SetTemporaryOrdinals. Safe because ordinal keys are immutable shadow key properties as EF doesn't run change detection on them.

Note that Cosmos has this issue too.

Issue 3: FK cascade to nested owned entities

When ordinal keys are reassigned on collection items (e.g. after removing an item), EF's relationship fixup cascades the key change to FK properties on nested owned entities (e.g. a Reference owned by a ThirdLevel in a collection). This marks those nested entries as Modified, but they aren't in EF's entries list either. I discovered this while adding an extra test for nested owned entity updates.

Fix: After materializing updates (which triggers ordinal reassignment and FK cascade), scan the state manager for any non-root entries promoted to Modified and add them to the entries list. The scan is scoped to non-root entities only to avoid interfering with entries EF manages directly.

@damieng damieng changed the title Fix entity states for owned entity collections EF-293: Fix entity states for owned entity collections Feb 18, 2026
@jbroumels
Copy link

I tested your branch against my solution as a direct dependency.
The strange issues I had seem all to be gone.
Great work!

@damieng
Copy link
Collaborator Author

damieng commented Feb 18, 2026

Thanks for your other PR - it also worked but I had concerns about the way it tackled the restoring or state and updating the keys being too different from what we and Cosmos do today.

I don't want to deviate too much from that not just because of potential regressions in areas we don't have test coverage but also because it's harder to stay aligned with EF changes if we're not using the same technique (the synthetic key code is based on the Cosmos providers hence they they have the same bug)

@jbroumels
Copy link

Yeah, I understand that. I was trying to figure out these problems for a few days and it's not so easy to see how it all fits together. Now finally, it works the same as with other providers!

@damieng damieng marked this pull request as ready for review February 18, 2026 16:23
@damieng damieng requested a review from a team as a code owner February 18, 2026 16:23
@damieng damieng requested review from ajcvickers and Copilot and removed request for Copilot February 18, 2026 16:23
Copilot AI review requested due to automatic review settings February 19, 2026 17:27
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses EF-293 by ensuring EF Core’s AcceptAllChanges sees entities whose state becomes Modified during MongoDB save preparation (root promotion + FK cascade from ordinal reassignment), and by preventing ordinal key updates from incorrectly flagging owned entries as modified. It also expands functional test coverage for repeated saves and nested owned collections.

Changes:

  • Update save pipeline to materialize Mongo updates and add any entries promoted to Modified during save prep into EF’s entries list for correct AcceptAllChanges behavior.
  • Prevent ordinal shadow key assignment from marking owned entries as modified (setModified: false).
  • Add/expand functional tests (sync + async) for owned collection adjustments, nested owned collections, and avoiding unintended root property overwrites; adjust Evergreen CI matrix to split macOS into its own variant.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/MongoDB.EntityFrameworkCore/Storage/MongoDatabaseWrapper.cs Ensures promoted roots and other entries promoted during save prep are included for AcceptAllChanges.
src/MongoDB.EntityFrameworkCore/Storage/MongoUpdate.cs Avoids marking entries modified when assigning store-generated ordinal keys.
tests/MongoDB.EntityFrameworkCore.FunctionalTests/Query/OwnedEntityTests.cs Adds theory-based sync/async coverage for repeated saves and nested owned collection modifications.
tests/MongoDB.EntityFrameworkCore.FunctionalTests/Design/Generated/EF10/SimpleContextModelBuilder.cs Updates generated model ID to match current model snapshot.
evergreen/evergreen.yml Splits macOS testing into a separate buildvariant and adjusts OS matrix.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

ajcvickers
ajcvickers previously approved these changes Feb 20, 2026
@damieng damieng changed the base branch from main to feature-select-projections February 23, 2026 12:36
@damieng damieng changed the base branch from feature-select-projections to main February 23, 2026 12:36
@damieng damieng dismissed ajcvickers’s stale review February 23, 2026 12:36

The base branch was changed.

@damieng damieng merged commit e23f821 into mongodb:main Feb 23, 2026
15 checks passed
@damieng damieng deleted the ef-293 branch February 23, 2026 13:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cosmos: removing a value from an owned collection leaves the change tracker in a bad state

3 participants