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());
}