Skip to content

Commit eff4df2

Browse files
committed
Configure the correct end as principal for self-ref collection with [ForeignKey]
Fixes #26364
1 parent bc24387 commit eff4df2

File tree

3 files changed

+50
-4
lines changed

3 files changed

+50
-4
lines changed

src/EFCore/Metadata/Conventions/ForeignKeyAttributeConvention.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,10 @@ public virtual void ProcessEntityTypeAdded(
116116
foreach (var navigation in foreignKeyNavigations)
117117
{
118118
entityTypeBuilder.HasRelationship(
119-
entityType, foreignKeyNavigations[0], setTargetAsPrincipal: true, fromDataAnnotation: true);
119+
entityType,
120+
navigation,
121+
setTargetAsPrincipal: navigation.GetMemberType().IsAssignableFrom(entityType.ClrType),
122+
fromDataAnnotation: true);
120123
}
121124
}
122125

src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2825,14 +2825,15 @@ private static InternalIndexBuilder DetachIndex(Index indexToDetach)
28252825
var navigationProperty = navigationToTarget?.MemberInfo;
28262826
var inverseProperty = inverseNavigation?.MemberInfo;
28272827
if (setTargetAsPrincipal == false
2828-
|| (inverseNavigation == null
2828+
|| (setTargetAsPrincipal == null
2829+
&& inverseNavigation == null
28292830
&& navigationProperty?.GetMemberType().IsAssignableFrom(
28302831
targetEntityType.ClrType)
28312832
== false))
28322833
{
2833-
// Target is expected to be dependent or only one nav specified and it can't be the nav to principal
2834+
// Target is dependent or only one nav specified and it can't be the nav to principal
28342835
return targetEntityType.Builder.HasRelationship(
2835-
Metadata, null, navigationToTarget, !setTargetAsPrincipal, configurationSource, required);
2836+
Metadata, inverseNavigation, navigationToTarget, setTargetAsPrincipal: true, configurationSource, required);
28362837
}
28372838

28382839
if (setTargetAsPrincipal == null

test/EFCore.Specification.Tests/DataAnnotationTestBase.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,6 +1429,48 @@ public class ProfileDetails12
14291429
public int Id { get; set; }
14301430
}
14311431

1432+
[ConditionalFact]
1433+
public virtual void Inverse_and_self_ref_ForeignKey()
1434+
{
1435+
var modelBuilder = CreateModelBuilder();
1436+
1437+
modelBuilder.Entity<MenuGroup>();
1438+
1439+
var model = Validate(modelBuilder);
1440+
1441+
var menuGroup = model.FindEntityType(typeof(MenuGroup));
1442+
var groupsNavigation = menuGroup.FindNavigation(nameof(MenuGroup.Groups));
1443+
Assert.Equal(nameof(MenuGroup.FkGroup), groupsNavigation.ForeignKey.Properties.Single().Name);
1444+
1445+
var pagesNavigation = menuGroup.FindNavigation(nameof(MenuGroup.Pages));
1446+
Assert.Equal(nameof(MenuPage.FkGroupNavigation), pagesNavigation.Inverse.Name);
1447+
Assert.Equal(nameof(MenuPage.FkGroup), pagesNavigation.ForeignKey.Properties.Single().Name);
1448+
}
1449+
1450+
protected class MenuGroup
1451+
{
1452+
public Guid Id { get; set; }
1453+
public Guid? FkGroup { get; set; }
1454+
1455+
[InverseProperty(nameof(MenuPage.FkGroupNavigation))]
1456+
public virtual ICollection<MenuPage> Pages { get; set; }
1457+
1458+
[ForeignKey(nameof(FkGroup))]
1459+
public virtual ICollection<MenuGroup> Groups { get; set; }
1460+
}
1461+
1462+
protected class MenuPage
1463+
{
1464+
public Guid Id { get; set; }
1465+
1466+
public Guid? FkGroup { get; set; }
1467+
1468+
[ForeignKey(nameof(FkGroup))]
1469+
[InverseProperty(nameof(MenuGroup.Pages))]
1470+
public virtual MenuGroup FkGroupNavigation { get; set; }
1471+
}
1472+
1473+
14321474
[ConditionalFact]
14331475
public virtual void Multiple_self_ref_ForeignKeys_on_navigations()
14341476
{

0 commit comments

Comments
 (0)