diff --git a/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs index 410beadaf54..85afff011c8 100644 --- a/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs @@ -50,6 +50,9 @@ public class ForeignKeyPropertyDiscoveryConvention : IPropertyFieldChangedConvention, IModelFinalizingConvention { + private static readonly bool UseOldBehavior34875 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue34875", out var enabled34875) && enabled34875; + /// /// Creates a new instance of . /// @@ -142,7 +145,7 @@ private IConventionForeignKeyBuilder ProcessForeignKey( && fkProperty.ClrType.IsNullableType() == foreignKey.IsRequired && fkProperty.GetContainingForeignKeys().All(otherFk => otherFk.IsRequired == foreignKey.IsRequired)) { - var newType = fkProperty.ClrType.MakeNullable(!foreignKey.IsRequired); + var newType = fkProperty.ClrType.MakeNullable(!foreignKey.IsRequired && (!fkProperty.IsKey() || UseOldBehavior34875)); if (fkProperty.ClrType != newType) { fkProperty.DeclaringType.Builder.Property( diff --git a/test/EFCore.Specification.Tests/ModelBuilding101ManyToManyTestBase.cs b/test/EFCore.Specification.Tests/ModelBuilding101ManyToManyTestBase.cs index f8bf1220ba2..c5f9b86fb40 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding101ManyToManyTestBase.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding101ManyToManyTestBase.cs @@ -737,6 +737,61 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) } } + [ConditionalFact] + public virtual void ManyToManyWithPayloadAndNavsToJoinClassShadowFKsTest() + => Model101Test(); + + protected class ManyToManyWithPayloadAndNavsToJoinClassShadowFKs + { + public class Post + { + public int Id { get; set; } + public List Tag { get; } = []; + public List PostTags { get; } = []; + } + + public class Tag + { + public int Id { get; set; } + public List Post { get; } = []; + public List PostTags { get; } = []; + } + + public class PostTag + { + } + + public class Context0 : Context101 + { + public DbSet Post + => Set(); + + public DbSet Tag + => Set(); + + protected override void OnModelCreating(ModelBuilder modelBuilder) + => modelBuilder.Entity() + .HasMany(e => e.Tag) + .WithMany(e => e.Post) + .UsingEntity( + l => l.HasOne().WithMany(t => t.PostTags), + r => r.HasOne().WithMany(p => p.PostTags), + j => { }); + } + + public class Context1 : Context0 + { + protected override void OnModelCreating(ModelBuilder modelBuilder) + => modelBuilder.Entity() + .HasMany(e => e.Tag) + .WithMany(e => e.Post) + .UsingEntity( + l => l.HasOne().WithMany(t => t.PostTags).HasForeignKey("TagId"), + r => r.HasOne().WithMany(p => p.PostTags).HasForeignKey("PostId"), + j => { }); + } + } + [ConditionalFact] public virtual void ManyToManyWithNoCascadeDeleteTest() => Model101Test();