From 4f1aa641d7325c2e85fcf608033e05084e18d917 Mon Sep 17 00:00:00 2001 From: leniency Date: Thu, 3 Feb 2022 18:45:30 -0800 Subject: [PATCH] Fix for the optimizer when an entity has a collection property that references itself. Fixes #27301 # Conflicts: # src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs --- .../CSharpRuntimeModelCodeGenerator.cs | 2 +- .../CSharpRuntimeModelCodeGeneratorTest.cs | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs index 2e1a73e86f5..81356d1d5c4 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs @@ -1400,7 +1400,7 @@ private static void AddNamespace(Type type, ISet namespaces) } var sequenceType = type.TryGetSequenceType(); - if (sequenceType != null) + if (sequenceType != null && sequenceType != type) { AddNamespace(sequenceType, namespaces); } diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpRuntimeModelCodeGeneratorTest.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpRuntimeModelCodeGeneratorTest.cs index 0994a8bb75b..af66a4e5a16 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpRuntimeModelCodeGeneratorTest.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpRuntimeModelCodeGeneratorTest.cs @@ -56,6 +56,20 @@ namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal { public class CSharpRuntimeModelCodeGeneratorTest { + + [ConditionalFact] + public void Self_referential_property() + => Test( + new TestModel.Internal.SelfReferentialDbContext(), + new CompiledModelCodeGenerationOptions(), + assertModel: model => + { + Assert.Single(model.GetEntityTypes()); + Assert.Same(model, model.FindRuntimeAnnotationValue("ReadOnlyModel")); + } + ); + + [ConditionalFact] public void Empty_model() { @@ -3659,6 +3673,18 @@ public class IdentityUser : TestModels.AspNetIdentity.IdentityUser { } + + + public class SelfReferentialEntity + { + public long Id { get; set; } + + public SelfReferentialProperty Collection { get; set; } + } + + public class SelfReferentialProperty : List + { + } } namespace Microsoft.EntityFrameworkCore.Scaffolding.TestModel.Internal @@ -3678,4 +3704,29 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(); } } + + public class SelfReferentialDbContext : ContextBase + { + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity( + eb => + { + eb.Property(e => e.Collection).HasConversion(typeof(SelfReferentialPropertyValueConverter)); + }); + } + } + + public class SelfReferentialPropertyValueConverter : ValueConverter + { + public SelfReferentialPropertyValueConverter() + : this(null) + { } + + public SelfReferentialPropertyValueConverter(ConverterMappingHints hints) + : base(v => null, v => null, hints) + { } + } }