From 39c0135f90f7a51729c3857e3ddd4e10ca4c5c94 Mon Sep 17 00:00:00 2001 From: Andriy Svyryd Date: Tue, 2 Nov 2021 18:10:52 -0700 Subject: [PATCH] Avoid NRE in ForeignKeyAttributeConvention Fixes #26436 --- .../ForeignKeyAttributeConvention.cs | 2 +- .../DataAnnotationTestBase.cs | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/EFCore/Metadata/Conventions/ForeignKeyAttributeConvention.cs b/src/EFCore/Metadata/Conventions/ForeignKeyAttributeConvention.cs index 6694cc571e6..fe14c220124 100644 --- a/src/EFCore/Metadata/Conventions/ForeignKeyAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/ForeignKeyAttributeConvention.cs @@ -345,7 +345,7 @@ var fkPropertiesOnDependentToPrincipal } } - return newRelationshipBuilder.HasForeignKey(fkPropertiesToSet, fromDataAnnotation: true); + return newRelationshipBuilder?.HasForeignKey(fkPropertiesToSet, fromDataAnnotation: true); } private static IConventionForeignKeyBuilder? SplitNavigationsToSeparateRelationships( diff --git a/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs b/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs index c7ebab2e2e6..078c8dd12d7 100644 --- a/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs +++ b/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs @@ -1105,6 +1105,45 @@ protected class Profile4 public virtual Login4 User { get; set; } } + [ConditionalFact] + public virtual void Required_and_ForeignKey_to_ForeignKey_can_be_overridden() + { + var modelBuilder = CreateModelBuilder(); + + modelBuilder.Entity() + .HasOne(p => p.Profile) + .WithOne(p => p.User) + .HasForeignKey("ProfileId"); + + var model = Validate(modelBuilder); + + var loginFk = GetProperty(model, "ProfileId").GetContainingForeignKeys().Single(); + Assert.True(loginFk.IsRequired); // This will be False after #15898 is fixed + Assert.True(loginFk.IsRequiredDependent); + + Assert.False(GetProperty(model, nameof(Profile3.Profile3Id)).IsForeignKey()); + } + + [Table("Employee")] + public class Employee1 + { + [Key] + [Column("EmployeeId")] + public decimal EmployeeId { get; set; } + + [ForeignKey("EmployeeId")] + public EmployeeDetail EmployeeDetail { get; set; } + } + + [Table("EmployeeDetail")] + public class EmployeeDetail + { + [Key] + public decimal EmployeeId { get; set; } + + public Employee1 Employee { get; set; } + } + [ConditionalFact] public virtual void ForeignKey_to_nothing() {