Skip to content

Scaffolding fails for a self-referencing many-to-many join table when both FKs yield the same navigation name - #38787

Open
ilkertskn wants to merge 2 commits into
dotnet:mainfrom
ilkertskn:fix/scaffold-self-referencing-many-to-many-navigation-names
Open

Scaffolding fails for a self-referencing many-to-many join table when both FKs yield the same navigation name#38787
ilkertskn wants to merge 2 commits into
dotnet:mainfrom
ilkertskn:fix/scaffold-self-referencing-many-to-many-navigation-names

Conversation

@ilkertskn

@ilkertskn ilkertskn commented Aug 11, 2026

Copy link
Copy Markdown
Contributor
  • The name generated for the left skip navigation was neither added to the existing identifiers nor present in the model when the right name was generated, and the identifier list is shared by both ends when the join table references a single entity type, so the uniquifier produced the same name twice and AddSkipNavigation threw, failing the whole scaffolding operation
  • Add the generated name to the identifiers so the right-hand side sees it
  • Add a test for a self-referencing join table whose foreign keys yield the same candidate name
  • I've read the guidelines for contributing and seen the walkthrough
  • I've posted a comment on an issue with a detailed description of how I am planning to contribute and got approval from a member of the team
  • The code builds and tests pass locally (also verified by our automated build checks)
  • Commit messages follow this format:
        Summary of the changes
        - Detail 1
        - Detail 2

        Fixes #bugnumber
  • Tests for the changes have been added (for bug fixes / features)
  • Code follows the same patterns and style as existing code in this repo

…ny-to-many join table

- The name generated for the left skip navigation was neither added to the existing identifiers nor
  present in the model when the right name was generated, and the identifier list is shared by both
  ends when the join table references a single entity type, so the uniquifier produced the same name
  twice and AddSkipNavigation threw, failing the whole scaffolding operation
- Add the generated name to the identifiers so the right-hand side sees it
- Add a test for a self-referencing join table whose foreign keys yield the same candidate name
@ilkertskn
ilkertskn requested a review from a team as a code owner August 11, 2026 22:50
@ilkertskn

Copy link
Copy Markdown
Contributor Author

@dotnet-policy-service agree

@AndriySvyryd
AndriySvyryd requested a lite review from Copilot August 12, 2026 00:27
@AndriySvyryd AndriySvyryd self-assigned this Aug 12, 2026
@AndriySvyryd AndriySvyryd added this to the 12.0.0 milestone Aug 12, 2026

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 reverse-engineering/scaffolding failure for self-referencing many-to-many join tables where both skip navigations end up with the same generated name, causing AddSkipNavigation to throw and scaffolding to fail.

Changes:

  • Ensures the left skip-navigation name is added to the existing identifier set before generating the right skip-navigation name (preventing duplicate-name generation in self-referencing join scenarios).
  • Adds a new regression test intended to cover colliding skip-navigation names on a self-referencing join table.

Reviewed changes

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

File Description
src/EFCore.Design/Scaffolding/Internal/RelationalScaffoldingModelFactory.cs Makes the left skip-navigation name visible to subsequent naming to avoid collisions when both ends share the same identifier list.
test/EFCore.Design.Tests/Scaffolding/Internal/RelationalScaffoldingModelFactoryTest.cs Adds a regression test for self-referencing many-to-many join-table skip-navigation name collisions.
Suppressed comments (1)

test/EFCore.Design.Tests/Scaffolding/Internal/RelationalScaffoldingModelFactoryTest.cs:2734

  • The assertions only check for uniqueness, which could still pass if the candidate names don’t collide (or if the uniquifier changes behavior). Tightening this to assert the expected collision resolution (e.g. Products and ProductsNavigation) makes the regression coverage more direct and stable.
        Assert.Equal(2, skipNavigationNames.Count);
        Assert.Equal(skipNavigationNames.Count, skipNavigationNames.Distinct().Count());

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants