Skip to content

Comments

Fix InvalidCastException in ArrayPropertyValues.ToObject() with nested nullable complex properties#37762

Open
AndriySvyryd wants to merge 1 commit intomainfrom
Issue37516
Open

Fix InvalidCastException in ArrayPropertyValues.ToObject() with nested nullable complex properties#37762
AndriySvyryd wants to merge 1 commit intomainfrom
Issue37516

Conversation

@AndriySvyryd
Copy link
Member

Fix issues with SetValues methods with nested nullable complex properties
Handle uninitialized complex collections when creating the initial original values.

Fixes #37516

Copy link

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 change-tracking value materialization for nested nullable complex properties (and related SetValues/OriginalValues behavior), addressing InvalidCastException scenarios like #37516 and ensuring compiled model scaffolding emits the necessary factories.

Changes:

  • Add/propagate nullable complex-property null-state handling across PropertyValues implementations and SetValues(...) flows.
  • Introduce EmptyOriginalValuesFactory plumbing to avoid initializing original snapshots from uninitialized complex collections (including compiled model scaffolding/baselines).
  • Add/expand unit tests covering ToObject()/SetValues(...) with nested nullable complex properties and complex collections.

Reviewed changes

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

Show a summary per file
File Description
src/EFCore/ChangeTracking/PropertyValues.cs Centralize computation of nullable complex properties for null-state tracking.
src/EFCore/ChangeTracking/Internal/EntryPropertyValues.cs Propagate nullable-complex null-state + enhance SetValues for nested complex scenarios.
src/EFCore/ChangeTracking/Internal/ArrayPropertyValues.cs Adjust ToObject/SetValues for nested nullable complex properties and complex collections.
src/EFCore/ChangeTracking/Internal/OriginalPropertyValues.cs Reconstruct original complex-collection elements from per-entry original snapshots.
src/EFCore/ChangeTracking/Internal/InternalEntryBase.cs Add skip-change-detection option for setting originals; avoid snapshot init when ordinals out of bounds.
src/EFCore/ChangeTracking/Internal/InternalEntryBase.OriginalValues.cs Add empty-original-values snapshot path.
src/EFCore/ChangeTracking/Internal/InternalEntryBase.InternalComplexCollectionEntry.cs Ensure original values exist when transitioning complex-collection state.
src/EFCore/ChangeTracking/Internal/InternalComplexEntry.cs Guard original-value reads on snapshot availability for deleted entries.
src/EFCore/ChangeTracking/Internal/IInternalEntry.cs Extend SetOriginalValue API with skip-change-detection option.
src/EFCore/ChangeTracking/Internal/CurrentPropertyValues.cs Thread skip-change-detection through SetValueInternal override.
src/EFCore/ChangeTracking/Internal/EmptyOriginalValuesFactoryFactory.cs New factory to generate empty original-values snapshots.
src/EFCore/Metadata/Internal/IRuntimeTypeBase.cs Add EmptyOriginalValuesFactory to runtime metadata surface.
src/EFCore/Metadata/Internal/TypeBase.cs Provide lazy-initialized EmptyOriginalValuesFactory implementation.
src/EFCore/Metadata/RuntimeTypeBase.cs Add runtime setter/getter for EmptyOriginalValuesFactory (compiled model support).
src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs Emit SetEmptyOriginalValuesFactory into generated runtime model code.
test/EFCore.Tests/ChangeTracking/Internal/PropertyValuesTest.cs Add coverage for ToObject/SetValues with nested nullable complex properties/collections.
test/EFCore.Specification.Tests/TestUtilities/DataGenerator.cs Support nullable enum inputs for combinatorial test data.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Triggers/DataEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Dynamic_schema/DataEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/DbFunctions/ObjectEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/DbFunctions/DataEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/CheckConstraints/DataEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedTypeEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedType0EntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DataEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/AutoIncrementEntityEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DataEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/AutoIncrementEntityEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Triggers/DataEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Tpc_Sprocs/PrincipalDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Tpc_Sprocs/PrincipalBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Tpc_Sprocs/DependentBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/SpatialTypesTest/SpatialTypesEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Key_sequence/DataEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Key_HiLo_sequence/DataEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Dynamic_schema/DataEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/DbFunctions/ObjectEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/DbFunctions/DataEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/CheckConstraints/DataEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedTypeEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedType0EntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Self_referential_property/SelfReferentialEntityEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/RelationshipCycles/PrincipalDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/RelationshipCycles/PrincipalBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/RelationshipCycles/DependentBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyEntityEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyDelegateEntityEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyConstructorEntityEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_proxies/LazyProxiesEntity2EntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_proxies/LazyProxiesEntity1EntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_manual/LazyProxiesEntity4EntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_manual/LazyProxiesEntity3EntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Global_namespace/EntityType1.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/ScaffoldingEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/IndexEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/IdentityUserEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/IdentityUser0EntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_value_converter/MyEntityEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_value_comparer/MyEntityEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_type_mapping/MyEntityEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_provider_value_comparer/MyEntityEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.
test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/Basic_cosmos_model/DataEntityType.cs Baseline updated for emitted EmptyOriginalValuesFactory.

Copy link
Member

@roji roji left a comment

Choose a reason for hiding this comment

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

🐑 🇮🇹

@roji roji assigned AndriySvyryd and unassigned roji Feb 21, 2026
…d nullable complex properties

Fix issues with SetValues methods with nested nullable complex properties

Fixes #37516

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Copilot AI review requested due to automatic review settings February 21, 2026 20:18
@AndriySvyryd AndriySvyryd enabled auto-merge (squash) February 21, 2026 20:19
Copy link

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

Copilot reviewed 22 out of 26 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • src/EFCore/Properties/CoreStrings.Designer.cs: Language not supported

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.

InvalidCastException with Complex Properties "OriginalValues.ToObject()" in 10.0.2

3 participants