Fix inverting identifying FK using wrong type and short-circuit principal type on attach#38423
Fix inverting identifying FK using wrong type and short-circuit principal type on attach#38423Copilot wants to merge 8 commits into
Conversation
|
@copilot Feel free to enhance the logic in SetOrAddForeignKey/CreateForeignKey, but make sure that this doesn't add code duplication |
…ort-circuit re-resolution Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR is presented as an investigation into remaining relationship/model-building behaviors in EF Core, but it also includes code changes that alter the attach/snapshot plumbing for relationships.
Changes:
- Capture and store the relationship’s principal entity type in
RelationshipSnapshot. - Thread the captured principal entity type into
InternalForeignKeyBuilder.Attachvia a new optional parameter.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/EFCore/Metadata/Internal/RelationshipSnapshot.cs | Stores PrincipalEntityType on snapshot creation and passes it into Relationship.Attach(...) during reattach. |
| src/EFCore/Metadata/Internal/InternalForeignKeyBuilder.cs | Extends Attach to accept an optional principalEntityType and prefers it when it appears valid/in-model. |
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>
All three items are now implemented (the previous PR shipped no code):
Validated against the full |
…ionship tests Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
…e guard Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Fixes two long-standing issues in EF Core's relationship-building engine.
1. Pass in principal type when attaching FK
RelationshipSnapshotnow capturesPrincipalEntityTypeand forwards it toInternalForeignKeyBuilder.Attach, which gains an optionalEntityType? principalEntityTypeparameter. When the principal is known and still in the model,Attachshort-circuits the heuristic re-resolution (InternalForeignKeyBuilder.cs~L3499–3540), improving perf. The short-circuit matches onClrTypeonly for non-shared types to avoid colliding distinct shared-type entities; the existing re-resolution remains for the principal-not-in-model case.Regression tests added in
InternalForeignKeyBuilderTest:Attach_uses_provided_principal_type_when_in_model— verifies the short-circuit fires when the captured principal is still in the model.Attach_does_not_bind_to_wrong_shared_type_principal_by_clr_type— registers two shared-type entities with the same CLR type; passing the wrong one must not cause incorrect binding (the!HasSharedClrTypeguard disables CLR-type matching for shared types).Attach_falls_back_to_model_lookup_when_provided_principal_is_not_in_model— verifies the heuristic fallback correctly resolves the principal when the captured entity is stale.2. Inverting identifying FK to derived no longer moves the FK to base
The invert branch of
SetRelatedTypes(InternalForeignKeyBuilder.cs~L1440–1441) usedLeastDerivedType, which collapsed onto the base when the requested type was a proper base of the old opposite end. This is the bug: inverting an identifying FK between a non-derived type and a derived type produced an FK between two non-derived types. The invert branch now keeps the more-derived end, so the inverted FK stays between the derived and non-derived type. Added regression testInverting_identifying_relationship_keeps_derived_dependent.