Skip to content

Fix compiled-model CreateRelationalModel() failure when an owned entity shares its owner's table#38428

Open
Copilot wants to merge 6 commits into
mainfrom
copilot/fix-create-relational-model-error
Open

Fix compiled-model CreateRelationalModel() failure when an owned entity shares its owner's table#38428
Copilot wants to merge 6 commits into
mainfrom
copilot/fix-create-relational-model-error

Conversation

Copilot AI commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Fixes #37981

A compiled model whose owned entity shares its owner's table (where the owner has an index/constraint) threw System.InvalidOperationException: Sequence contains no elements from CreateRelationalModel() at runtime, despite compiling successfully.

Root cause

RelationalCSharpRuntimeAnnotationCodeGenerator emitted unique-constraint/index/trigger creation inline, guarded by tableMapping == table.EntityTypeMappings.Last(). When an owned entity (e.g. Author) shares its owner's (Post) table and its mapping is the last EntityTypeMapping but is iterated before the owner, an index (e.g. IX_Posts_BlogId) was generated before the referenced column's mapping existed. SetRowIndexValueFactory(...) then hit ColumnBase.GetDefaultStoreTypeMapping(), which requires at least one column mapping — hence the empty-sequence failure.

Changes

  • RelationalCSharpRuntimeAnnotationCodeGenerator: moved unique-constraint, index, and trigger emission out of the per-ITableMapping path into a CreateTableConstraints pass over model.Tables, run after all column mappings are emitted, guaranteeing every referenced column is mapped before constraints/indexes are built.
  • Ordering: foreign keys remain in a separate model.Tables pass after CreateTableConstraints. Generated FKs resolve their principal's unique constraint at runtime via principalTable.FindUniqueConstraint(name)!, and IRelationalModel.Tables is not topologically ordered — so all unique constraints must be emitted before any FK. The foreignKeysOnly parameter was removed; the FK loop is inlined.
  • Tests: added the Owned_entity_sharing_table_with_owner_that_has_an_index regression test (Blog/Post/Author).
  • Baselines: added Sqlite/SqlServer baselines for the new test and regenerated affected existing baselines (BigModel_with_JSON_columns, ComplexTypes, Tpc_Sprocs) — pure relocations of constraint/index emission after column mappings.

Generated code, before vs after

// before: index emitted while processing Author's (last) mapping — blogIdColumn has no mapping yet
var iX_Posts_BlogId = new TableIndex("IX_Posts_BlogId", postsTable, new[] { blogIdColumn }, false);
iX_Posts_BlogId.SetRowIndexValueFactory(new SimpleRowIndexValueFactory<int>(iX_Posts_BlogId)); // throws
...
RelationalModel.CreateColumnMapping(blogIdColumn, post.FindProperty("BlogId")!, postsTableMapping0);

// after: all column mappings first, then constraints/indexes in the post-pass
RelationalModel.CreateColumnMapping(blogIdColumn, post.FindProperty("BlogId")!, postsTableMapping0);
...
var iX_Posts_BlogId = new TableIndex("IX_Posts_BlogId", postsTable, new[] { blogIdColumn }, false);
iX_Posts_BlogId.SetRowIndexValueFactory(new SimpleRowIndexValueFactory<int>(iX_Posts_BlogId));

…owner's table

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix CreateRelationalModel() to handle owned entities Fix compiled model CreateRelationalModel() failure with owned entity sharing owner's table Jun 13, 2026
Copilot AI requested a review from AndriySvyryd June 13, 2026 01:25
@AndriySvyryd AndriySvyryd requested a review from Copilot June 13, 2026 04:25

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Fixes a runtime failure when creating the relational model from a compiled model in scenarios where an owned entity shares its owner’s table and the owner has an index/constraint. The fix ensures table constraints/indexes/triggers are generated only after all column mappings exist, preventing empty-sequence failures during value-factory setup.

Changes:

  • Updated RelationalCSharpRuntimeAnnotationCodeGenerator to generate unique constraints, indexes, and triggers in a dedicated post-pass over model.Tables, after all column mappings are emitted (and before FK constraints).
  • Added a regression test (Owned_entity_sharing_table_with_owner_that_has_an_index) to force relational-model creation in the problematic mapping order and validate index presence.
  • Regenerated/updated compiled-model scaffolding baselines (primarily reordering constraint/index emission after mappings) and added new Sqlite/SqlServer baselines for the new test.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/EFCore.Relational/Design/Internal/RelationalCSharpRuntimeAnnotationCodeGenerator.cs Moves table constraint/index/trigger emission to a table-level post-pass after column mappings are generated.
test/EFCore.Relational.Specification.Tests/Scaffolding/CompiledModelRelationalTestBase.cs Adds regression test and supporting Blog/Post/Author types for the owned-shared-table + index scenario.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Tpc_Sprocs/DbContextModelBuilder.cs Baseline update reflecting reordered constraint/index emission.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/ComplexTypes/DbContextModelBuilder.cs Baseline update reflecting reordered constraint/index emission.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DbContextModelBuilder.cs Baseline update reflecting reordered constraint/index emission.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DbContextModelBuilder.cs Baseline update reflecting reordered constraint/index emission.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/DbContextAssemblyAttributes.cs New baseline assembly attributes for the SqlServer provider.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/DbContextModel.cs New baseline runtime model for the SqlServer provider.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/DbContextModelBuilder.cs New baseline relational model builder output for the SqlServer provider.
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/BlogEntityType.cs New baseline entity type for Blog (SqlServer).
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/BlogUnsafeAccessors.cs New baseline unsafe accessors for Blog (SqlServer).
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/PostEntityType.cs New baseline entity type for Post (SqlServer).
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/PostUnsafeAccessors.cs New baseline unsafe accessors for Post (SqlServer).
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/AuthorEntityType.cs New baseline entity type for owned Author (SqlServer).
test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/AuthorUnsafeAccessors.cs New baseline unsafe accessors for Author (SqlServer).
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/DbContextAssemblyAttributes.cs New baseline assembly attributes for the Sqlite provider.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/DbContextModel.cs New baseline runtime model for the Sqlite provider.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/DbContextModelBuilder.cs New baseline relational model builder output for the Sqlite provider.
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/BlogEntityType.cs New baseline entity type for Blog (Sqlite).
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/BlogUnsafeAccessors.cs New baseline unsafe accessors for Blog (Sqlite).
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/PostEntityType.cs New baseline entity type for Post (Sqlite).
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/PostUnsafeAccessors.cs New baseline unsafe accessors for Post (Sqlite).
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/AuthorEntityType.cs New baseline entity type for owned Author (Sqlite).
test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Owned_entity_sharing_table_with_owner_that_has_an_index/AuthorUnsafeAccessors.cs New baseline unsafe accessors for Author (Sqlite).

Copilot AI and others added 2 commits June 13, 2026 04:36
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Copilot AI changed the title Fix compiled model CreateRelationalModel() failure with owned entity sharing owner's table Fix compiled-model CreateRelationalModel() failure when an owned entity shares its owner's table Jun 16, 2026
…atory comment

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Copilot AI requested a review from AndriySvyryd June 17, 2026 05:06
@AndriySvyryd AndriySvyryd marked this pull request as ready for review June 17, 2026 05:15
@AndriySvyryd AndriySvyryd requested a review from a team as a code owner June 17, 2026 05:15

Copilot AI left a comment

Copy link
Copy Markdown

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 24 out of 24 changed files in this pull request and generated no new comments.

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.

Compiled model's CreateRelationalModel() fails when model contains owned entity

3 participants