Skip to content

Commit

Permalink
Configure the correct end as principal for self-ref collection with […
Browse files Browse the repository at this point in the history
…ForeignKey]

Fixes #26364
  • Loading branch information
AndriySvyryd committed Oct 15, 2021
1 parent bc24387 commit eff4df2
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ public virtual void ProcessEntityTypeAdded(
foreach (var navigation in foreignKeyNavigations)
{
entityTypeBuilder.HasRelationship(
entityType, foreignKeyNavigations[0], setTargetAsPrincipal: true, fromDataAnnotation: true);
entityType,
navigation,
setTargetAsPrincipal: navigation.GetMemberType().IsAssignableFrom(entityType.ClrType),
fromDataAnnotation: true);
}
}

Expand Down
7 changes: 4 additions & 3 deletions src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2825,14 +2825,15 @@ private static InternalIndexBuilder DetachIndex(Index indexToDetach)
var navigationProperty = navigationToTarget?.MemberInfo;
var inverseProperty = inverseNavigation?.MemberInfo;
if (setTargetAsPrincipal == false
|| (inverseNavigation == null
|| (setTargetAsPrincipal == null
&& inverseNavigation == null
&& navigationProperty?.GetMemberType().IsAssignableFrom(
targetEntityType.ClrType)
== false))
{
// Target is expected to be dependent or only one nav specified and it can't be the nav to principal
// Target is dependent or only one nav specified and it can't be the nav to principal
return targetEntityType.Builder.HasRelationship(
Metadata, null, navigationToTarget, !setTargetAsPrincipal, configurationSource, required);
Metadata, inverseNavigation, navigationToTarget, setTargetAsPrincipal: true, configurationSource, required);
}

if (setTargetAsPrincipal == null
Expand Down
42 changes: 42 additions & 0 deletions test/EFCore.Specification.Tests/DataAnnotationTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1429,6 +1429,48 @@ public class ProfileDetails12
public int Id { get; set; }
}

[ConditionalFact]
public virtual void Inverse_and_self_ref_ForeignKey()
{
var modelBuilder = CreateModelBuilder();

modelBuilder.Entity<MenuGroup>();

var model = Validate(modelBuilder);

var menuGroup = model.FindEntityType(typeof(MenuGroup));
var groupsNavigation = menuGroup.FindNavigation(nameof(MenuGroup.Groups));
Assert.Equal(nameof(MenuGroup.FkGroup), groupsNavigation.ForeignKey.Properties.Single().Name);

var pagesNavigation = menuGroup.FindNavigation(nameof(MenuGroup.Pages));
Assert.Equal(nameof(MenuPage.FkGroupNavigation), pagesNavigation.Inverse.Name);
Assert.Equal(nameof(MenuPage.FkGroup), pagesNavigation.ForeignKey.Properties.Single().Name);
}

protected class MenuGroup
{
public Guid Id { get; set; }
public Guid? FkGroup { get; set; }

[InverseProperty(nameof(MenuPage.FkGroupNavigation))]
public virtual ICollection<MenuPage> Pages { get; set; }

[ForeignKey(nameof(FkGroup))]
public virtual ICollection<MenuGroup> Groups { get; set; }
}

protected class MenuPage
{
public Guid Id { get; set; }

public Guid? FkGroup { get; set; }

[ForeignKey(nameof(FkGroup))]
[InverseProperty(nameof(MenuGroup.Pages))]
public virtual MenuGroup FkGroupNavigation { get; set; }
}


[ConditionalFact]
public virtual void Multiple_self_ref_ForeignKeys_on_navigations()
{
Expand Down

0 comments on commit eff4df2

Please sign in to comment.