From 777d619b03ad1b63ad78e5768f9de35fc8e2ad57 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Aug 2026 20:36:51 +0000 Subject: [PATCH 1/4] Initial plan From 176fa8bb85c9290bafaf593f4a8cf3131bb621c7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Aug 2026 20:41:47 +0000 Subject: [PATCH 2/4] Resolve complex-type properties when mapping keys/FKs/indexes in RuntimeModelConvention Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- src/EFCore/Metadata/Conventions/RuntimeModelConvention.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/EFCore/Metadata/Conventions/RuntimeModelConvention.cs b/src/EFCore/Metadata/Conventions/RuntimeModelConvention.cs index 8ed18e3dcc2..ffd397ab072 100644 --- a/src/EFCore/Metadata/Conventions/RuntimeModelConvention.cs +++ b/src/EFCore/Metadata/Conventions/RuntimeModelConvention.cs @@ -685,7 +685,7 @@ private RuntimeForeignKey Create(IForeignKey foreignKey, RuntimeEntityType runti { var principalEntityType = runtimeEntityType.Model.FindEntityType(foreignKey.PrincipalEntityType.Name)!; return runtimeEntityType.AddForeignKey( - runtimeEntityType.FindProperties(foreignKey.Properties.Select(p => p.Name))!, + foreignKey.Properties.Select(p => FindRuntimeProperty(runtimeEntityType, p)).ToArray(), GetKey(foreignKey.PrincipalKey, principalEntityType), principalEntityType, foreignKey.DeleteBehavior, @@ -810,7 +810,7 @@ private RuntimeSkipNavigation Create(ISkipNavigation navigation, RuntimeEntityTy /// The corresponding read-optimized foreign key. protected virtual RuntimeForeignKey GetForeignKey(IForeignKey foreignKey, RuntimeEntityType entityType) => entityType.FindDeclaredForeignKeys( - entityType.FindProperties(foreignKey.Properties.Select(p => p.Name))!) + foreignKey.Properties.Select(p => FindRuntimeProperty(entityType, p)).ToArray()) .Single(fk => fk.PrincipalEntityType.Name == foreignKey.PrincipalEntityType.Name && fk.PrincipalKey.Properties.Select(p => p.Name).SequenceEqual( foreignKey.PrincipalKey.Properties.Select(p => p.Name))); @@ -822,7 +822,7 @@ protected virtual RuntimeForeignKey GetForeignKey(IForeignKey foreignKey, Runtim /// The declaring entity type. /// The corresponding read-optimized key. protected virtual RuntimeKey GetKey(IKey key, RuntimeEntityType entityType) - => entityType.FindKey(entityType.FindProperties(key.Properties.Select(p => p.Name))!)!; + => entityType.FindKey(key.Properties.Select(p => FindRuntimeProperty(entityType, p)).ToArray())!; /// /// Gets the corresponding index in the read-optimized model. @@ -832,7 +832,7 @@ protected virtual RuntimeKey GetKey(IKey key, RuntimeEntityType entityType) /// The corresponding read-optimized index. protected virtual RuntimeIndex GetIndex(IIndex index, RuntimeEntityType entityType) => index.Name == null - ? entityType.FindIndex(entityType.FindProperties(index.Properties.Select(p => p.Name))!)! + ? entityType.FindIndex(index.Properties.Select(p => FindRuntimePropertyBase(entityType, p)).ToArray())! : entityType.FindIndex(index.Name)!; /// From 5e1242390309748a6eabde4d0a6031a404d6ef7a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Aug 2026 20:50:22 +0000 Subject: [PATCH 3/4] Add regression test for FK referencing key on complex type property Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- .../ModelBuilderTest.ComplexType.cs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ComplexType.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ComplexType.cs index f06b500d0b4..a97b9238202 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ComplexType.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ComplexType.cs @@ -2312,6 +2312,37 @@ public virtual void Can_define_alternate_key_on_complex_property_via_string_dott Assert.Same(entityType, alternateKey.DeclaringEntityType); } + [Fact] + public virtual void Can_use_alternate_key_on_complex_property_as_principal_key() + { + var modelBuilder = CreateModelBuilder(); + + modelBuilder + .Ignore() + .Ignore() + .Entity(b => + { + b.Ignore(e => e.Customer); + b.Ignore(e => e.CollectionQuarks); + b.Ignore(e => e.QuarksCollection); + b.Ignore(e => e.DoubleProperty); + b.HasAlternateKey(e => e.Quarks.Up); + b.HasMany(e => e.Customers).WithOne() + .HasForeignKey("ParentUp") + .HasPrincipalKey("Quarks.Up"); + }); + + var model = modelBuilder.FinalizeModel(); + var entityType = model.FindEntityType(typeof(ComplexProperties))!; + var quarksType = entityType.GetComplexProperties().Single(p => p.Name == nameof(ComplexProperties.Quarks)) + .ComplexType; + var upProperty = quarksType.FindProperty(nameof(Quarks.Up))!; + + var foreignKey = model.FindEntityType(typeof(Customer))!.GetForeignKeys() + .Single(fk => fk.PrincipalEntityType == entityType); + Assert.Same(upProperty, foreignKey.PrincipalKey.Properties.Single()); + } + [Fact] public virtual void Can_define_index_on_complex_property_via_lambda() { From 736ae177e8cc46bff8691dcb112ea06a7a9a301b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Aug 2026 22:25:01 +0000 Subject: [PATCH 4/4] Fix complex key regression test for Cosmos Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- .../ModelBuilding/ModelBuilderTest.ComplexType.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ComplexType.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ComplexType.cs index a97b9238202..3100cb5d3aa 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ComplexType.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ComplexType.cs @@ -2338,7 +2338,7 @@ public virtual void Can_use_alternate_key_on_complex_property_as_principal_key() .ComplexType; var upProperty = quarksType.FindProperty(nameof(Quarks.Up))!; - var foreignKey = model.FindEntityType(typeof(Customer))!.GetForeignKeys() + var foreignKey = model.GetEntityTypes().Single(t => t.ClrType == typeof(Customer)).GetForeignKeys() .Single(fk => fk.PrincipalEntityType == entityType); Assert.Same(upProperty, foreignKey.PrincipalKey.Properties.Single()); }