Skip to content

[release/10.0] Fix nullable complex property discriminator changes not persisted#38134

Open
Copilot wants to merge 6 commits intorelease/10.0from
copilot/fix-nullable-complex-property-discriminator
Open

[release/10.0] Fix nullable complex property discriminator changes not persisted#38134
Copilot wants to merge 6 commits intorelease/10.0from
copilot/fix-nullable-complex-property-discriminator

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 17, 2026

Fixes #38119

Description
When a nullable complex property with a discriminator transitions from null to non-null, the discriminator value was not being saved to the database. This happened because complex type discriminators were configured with PropertySaveBehavior.Throw (same as entity type discriminators), which caused them to be skipped in DetectComplexPropertyChange() and would throw in PrepareToSave() if they were marked as modified.

Customer impact
Setting a nullable complex property with discriminator to a non-null value on an existing entity would appear to save successfully, but the discriminator column would remain null/empty. On subsequent reads, EF Core would see the null discriminator and materialize the complex property as null, losing the data the user expected to be saved. No workaround exists short of raw SQL to update the discriminator column.

How found
Two user reports on 10.0.6.

Regression
No, nullable complex properties are new in 10.0.0

Testing
6 new tests added, 1 existing test updated with roundtrip verification.

Risk
Low. Changes are scoped to complex type discriminator configuration and change detection. Quirk added.

Copilot AI and others added 2 commits April 17, 2026 21:34
…zed (#38119)

Stop marking complex type discriminators as PropertySaveBehavior.Throw
so they can be properly included in update operations.

Set discriminator values when nullable complex properties transition
between null and non-null states.

Add AppContext quirk for backward compatibility.
Add tests for null→non-null, non-null→null, and nested scenarios.

Agent-Logs-Url: https://github.com/dotnet/efcore/sessions/ac816eeb-ca12-43b0-8cfe-a7e4aeb83167

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix changes of nullable complex property with discriminator not recognized [release/10.0] Fix nullable complex property discriminator changes not persisted Apr 17, 2026
Copilot AI requested a review from AndriySvyryd April 17, 2026 21:39
@AndriySvyryd AndriySvyryd requested a review from Copilot April 17, 2026 22:04
Copy link
Copy Markdown

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

Fixes persistence of complex type discriminator values when a nullable complex property transitions between null and non-null, preventing silent data loss on subsequent materialization.

Changes:

  • Adjust complex type discriminator properties to use PropertySaveBehavior.Save (behind Microsoft.EntityFrameworkCore.Issue38119 switch).
  • Update ChangeDetector.DetectComplexPropertyChange to set/clear the discriminator shadow value on nullability transitions (behind the same switch).
  • Add/extend specification tests to validate null↔non-null roundtrips (including nested complex types).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs Adds new roundtrip coverage for nullable complex properties with discriminators; extends existing test to verify cross-context materialization.
src/EFCore/Metadata/Internal/InternalComplexTypeBuilder.cs Overrides discriminator property creation for complex types to allow updates via AfterSave(Save) under an AppContext quirk switch.
src/EFCore/ChangeTracking/Internal/ChangeDetector.cs Ensures discriminator shadow values are set/cleared when nullable complex properties flip between null and non-null.

Comment thread src/EFCore/ChangeTracking/Internal/ChangeDetector.cs Outdated
Comment thread src/EFCore/ChangeTracking/Internal/ChangeDetector.cs Outdated
Comment thread src/EFCore/ChangeTracking/Internal/ChangeDetector.cs Outdated
… InternalComplexTypeBuilder.UseOldBehavior38119; fix comment

Agent-Logs-Url: https://github.com/dotnet/efcore/sessions/519f1a56-e9a0-4b07-acaf-d153dc80b390

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Copilot AI requested a review from AndriySvyryd April 17, 2026 22:18
@AndriySvyryd AndriySvyryd marked this pull request as ready for review April 17, 2026 22:19
@AndriySvyryd AndriySvyryd requested a review from a team as a code owner April 17, 2026 22:19
Copilot AI review requested due to automatic review settings April 17, 2026 22:19
@AndriySvyryd AndriySvyryd assigned roji and unassigned AndriySvyryd and Copilot Apr 17, 2026
Copy link
Copy Markdown

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

Fixes persistence/materialization of nullable complex properties that use discriminators by ensuring the discriminator value is updated and allowed to be saved when the complex property transitions between null and non-null.

Changes:

  • Configure complex-type discriminator properties to use PropertySaveBehavior.Save (with an AppContext switch to retain old behavior).
  • Update change detection to set the discriminator shadow value on nullable complex property nullability transitions.
  • Extend/specify coverage with new roundtrip tests (including a nested nullable complex type case) and strengthen an existing test to verify persistence across contexts.

Reviewed changes

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

File Description
test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs Adds roundtrip regression tests for Issue38119 and updates an existing discriminator test to verify persistence across contexts.
src/EFCore/Metadata/Internal/InternalComplexTypeBuilder.cs Overrides discriminator property creation for complex types to set AfterSave to Save, guarded by an AppContext quirk switch.
src/EFCore/ChangeTracking/Internal/ChangeDetector.cs Sets discriminator shadow property values when nullable complex properties transition between null/non-null to ensure correct persistence and subsequent materialization.

Comment thread src/EFCore/ChangeTracking/Internal/ChangeDetector.cs Outdated
Comment thread test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@AndriySvyryd AndriySvyryd requested review from artl93 and Copilot April 17, 2026 22:34
@AndriySvyryd
Copy link
Copy Markdown
Member

@artl93

Copy link
Copy Markdown

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

Fixes EF Core 10.0 regression where complex type discriminator values weren’t persisted when an optional (nullable) complex property transitioned between null and non-null, which could lead to data loss on subsequent reads.

Changes:

  • Configure complex-type discriminator properties to use AfterSave(PropertySaveBehavior.Save) (with an AppContext quirk switch to revert).
  • Update change detection for nullable complex properties to set/clear the discriminator value when transitioning between null and non-null.
  • Add/adjust specification tests to validate roundtrips for nullable complex types with discriminators (including nested cases).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs Adds new roundtrip tests for nullable complex discriminators and strengthens an existing discriminator test with roundtrip verification.
src/EFCore/Metadata/Internal/InternalComplexTypeBuilder.cs Changes complex discriminator configuration so discriminator can be saved on updates (plus quirk switch).
src/EFCore/ChangeTracking/Internal/ChangeDetector.cs Sets/clears complex discriminator value during DetectComplexPropertyChange for null-state transitions.

Comment thread src/EFCore/ChangeTracking/Internal/ChangeDetector.cs Outdated
Comment thread src/EFCore/ChangeTracking/Internal/ChangeDetector.cs Outdated
…icit discriminator value, and null discriminator tests

Agent-Logs-Url: https://github.com/dotnet/efcore/sessions/153c52d0-a077-43d9-8ef7-dbf5e588039f

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
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.

Changes of nullable complex property with discriminator are not recognized

4 participants