Skip to content

Commit

Permalink
Prevent stack overflow for self-referencing PK-to-PK relationships
Browse files Browse the repository at this point in the history
Fixes #9478
  • Loading branch information
AndriySvyryd committed Aug 23, 2017
1 parent d3bc450 commit c907a9d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ private string GetDefaultColumnName()
{
foreach (var fk in entityType.FindForeignKeys(pk.Properties))
{
if (!fk.PrincipalKey.IsPrimaryKey())
if (!fk.PrincipalKey.IsPrimaryKey()
|| fk.PrincipalKey == pk)
{
continue;
}
Expand Down
31 changes: 31 additions & 0 deletions test/EFCore.Tests/ModelBuilding/OneToOneTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2443,6 +2443,8 @@ public virtual void Creates_self_referencing_FK_with_navigation_to_principal()

modelBuilder.Entity<SelfRef>().HasOne(e => e.SelfRef1).WithOne();

modelBuilder.Validate();

var fk = entityType.FindNavigation(nameof(SelfRef.SelfRef1)).ForeignKey;
var conventionFk = entityType.FindNavigation(nameof(SelfRef.SelfRef2)).ForeignKey;

Expand Down Expand Up @@ -2470,6 +2472,8 @@ public virtual void Creates_self_referencing_FK_with_navigation_to_dependent()

modelBuilder.Entity<SelfRef>().HasOne<SelfRef>().WithOne(e => e.SelfRef1);

modelBuilder.Validate();

var fk = entityType.FindNavigation(nameof(SelfRef.SelfRef1)).ForeignKey;
var conventionFk = entityType.FindNavigation(nameof(SelfRef.SelfRef2)).ForeignKey;

Expand All @@ -2483,6 +2487,33 @@ public virtual void Creates_self_referencing_FK_with_navigation_to_dependent()
Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique);
}

[Fact]
public virtual void Creates_self_referencing_FK_on_PK()
{
var modelBuilder = CreateModelBuilder();
modelBuilder.Entity<SelfRef>(
eb =>
{
eb.HasKey(e => e.Id);
});

var entityType = modelBuilder.Model.FindEntityType(typeof(SelfRef));

modelBuilder.Entity<SelfRef>().HasOne(e => e.SelfRef1).WithOne(e => e.SelfRef2).HasForeignKey<SelfRef>(e => e.Id);

modelBuilder.Validate();

var fk = entityType.FindNavigation(nameof(SelfRef.SelfRef1)).ForeignKey;

Assert.Equal(fk.Properties, entityType.FindPrimaryKey().Properties);
Assert.Equal(fk.PrincipalKey, entityType.FindPrimaryKey());
Assert.Equal(nameof(SelfRef.SelfRef1), fk.DependentToPrincipal?.Name);
Assert.Equal(nameof(SelfRef.SelfRef2), fk.PrincipalToDependent?.Name);
Assert.Equal(2, entityType.GetNavigations().Count());
Assert.Equal(0, fk.DeclaringEntityType.GetIndexes().Count());
Assert.Equal(1, fk.DeclaringEntityType.GetForeignKeys().Count());
}

[Fact]
public virtual void Principal_and_dependent_can_be_flipped_when_self_referencing_with_navigation_to_principal()
{
Expand Down

0 comments on commit c907a9d

Please sign in to comment.