[release/10.0] Fix nullable complex property discriminator changes not persisted#38134
[release/10.0] Fix nullable complex property discriminator changes not persisted#38134Copilot wants to merge 6 commits intorelease/10.0from
Conversation
…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>
Agent-Logs-Url: https://github.com/dotnet/efcore/sessions/ac816eeb-ca12-43b0-8cfe-a7e4aeb83167 Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
There was a problem hiding this comment.
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(behindMicrosoft.EntityFrameworkCore.Issue38119switch). - Update
ChangeDetector.DetectComplexPropertyChangeto 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. |
… 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>
There was a problem hiding this comment.
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. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
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
nulland 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. |
…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>
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 inDetectComplexPropertyChange()and would throw inPrepareToSave()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.