Skip to content

Commit 0a61b4a

Browse files
authored
Stop specifying incorrect column name in snapshot for owned type of generic entity type (#32937)
Fixes #32763
1 parent c825b05 commit 0a61b4a

File tree

2 files changed

+155
-1
lines changed

2 files changed

+155
-1
lines changed

src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,9 @@ public static string GetDefaultColumnName(this IReadOnlyProperty property)
183183
var foreignKey = property.GetContainingForeignKeys().First();
184184
var principalEntityType = foreignKey.PrincipalEntityType;
185185
if (principalEntityType is { HasSharedClrType: false, ClrType.IsConstructedGenericType: true }
186-
&& foreignKey.DependentToPrincipal == null)
186+
&& foreignKey.DependentToPrincipal == null
187+
&& (principalEntityType.GetTableName() != foreignKey.DeclaringEntityType.GetTableName()
188+
|| principalEntityType.GetSchema() != foreignKey.DeclaringEntityType.GetSchema()))
187189
{
188190
var principalProperty = property.FindFirstPrincipal()!;
189191
var principalName = principalEntityType.ShortName();

test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,25 @@ public class FooExtension<T>
608608
public T Bar { get; set; }
609609
}
610610

611+
public class Parrot<TChild>
612+
{
613+
public int Id { get; set; }
614+
public string Name { get; set; }
615+
public TChild Child { get; set; }
616+
}
617+
618+
public class Parrot
619+
{
620+
public int Id { get; set; }
621+
public string Name { get; set; }
622+
public Beak Child { get; set; }
623+
}
624+
625+
public class Beak
626+
{
627+
public string Name { get; set; }
628+
}
629+
611630
#region Model
612631

613632
[ConditionalFact]
@@ -4889,6 +4908,139 @@ public virtual void Property_column_name_is_stored_in_snapshot_when_DefaultColum
48894908
var property = entityType.FindProperty("FooExtensionId");
48904909
Assert.NotNull(property);
48914910
Assert.Equal("FooExtension<BarA>Id", property.GetColumnName());
4911+
4912+
Assert.Collection(
4913+
model.GetRelationalModel().Tables,
4914+
t =>
4915+
{
4916+
4917+
Assert.Equal("BarBase", t.Name);
4918+
Assert.Equal(["Id", "Discriminator", "FooExtension<BarA>Id"], t.Columns.Select(t => t.Name));
4919+
},
4920+
t =>
4921+
{
4922+
4923+
Assert.Equal("FooExtension<BarA>", t.Name);
4924+
Assert.Equal(["Id"], t.Columns.Select(t => t.Name));
4925+
});
4926+
});
4927+
4928+
[ConditionalFact]
4929+
public virtual void Generic_entity_type_with_owned_entities()
4930+
=> Test(
4931+
modelBuilder => modelBuilder.Entity<Parrot<Beak>>().OwnsOne(e => e.Child),
4932+
AddBoilerPlate(
4933+
"""
4934+
modelBuilder
4935+
.HasDefaultSchema("DefaultSchema")
4936+
.HasAnnotation("Relational:MaxIdentifierLength", 128);
4937+
4938+
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
4939+
4940+
modelBuilder.Entity("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Parrot<Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Beak>", b =>
4941+
{
4942+
b.Property<int>("Id")
4943+
.ValueGeneratedOnAdd()
4944+
.HasColumnType("int");
4945+
4946+
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
4947+
4948+
b.Property<string>("Name")
4949+
.HasColumnType("nvarchar(max)");
4950+
4951+
b.HasKey("Id");
4952+
4953+
b.ToTable("Parrot<Beak>", "DefaultSchema");
4954+
});
4955+
4956+
modelBuilder.Entity("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Parrot<Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Beak>", b =>
4957+
{
4958+
b.OwnsOne("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Beak", "Child", b1 =>
4959+
{
4960+
b1.Property<int>("ParrotId")
4961+
.HasColumnType("int");
4962+
4963+
b1.Property<string>("Name")
4964+
.HasColumnType("nvarchar(max)");
4965+
4966+
b1.HasKey("ParrotId");
4967+
4968+
b1.ToTable("Parrot<Beak>", "DefaultSchema");
4969+
4970+
b1.WithOwner()
4971+
.HasForeignKey("ParrotId");
4972+
});
4973+
4974+
b.Navigation("Child");
4975+
});
4976+
"""),
4977+
model =>
4978+
{
4979+
var parentType = model.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Parrot<Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Beak>");
4980+
Assert.NotNull(parentType);
4981+
Assert.NotNull(parentType.FindNavigation("Child")!.TargetEntityType);
4982+
4983+
var table = model.GetRelationalModel().Tables.Single();
4984+
Assert.Equal(["Id", "Child_Name", "Name"], table.Columns.Select(t => t.Name));
4985+
});
4986+
4987+
[ConditionalFact]
4988+
public virtual void Non_generic_entity_type_with_owned_entities()
4989+
=> Test(
4990+
modelBuilder => modelBuilder.Entity<Parrot>().OwnsOne(e => e.Child),
4991+
AddBoilerPlate(
4992+
"""
4993+
modelBuilder
4994+
.HasDefaultSchema("DefaultSchema")
4995+
.HasAnnotation("Relational:MaxIdentifierLength", 128);
4996+
4997+
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
4998+
4999+
modelBuilder.Entity("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Parrot", b =>
5000+
{
5001+
b.Property<int>("Id")
5002+
.ValueGeneratedOnAdd()
5003+
.HasColumnType("int");
5004+
5005+
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
5006+
5007+
b.Property<string>("Name")
5008+
.HasColumnType("nvarchar(max)");
5009+
5010+
b.HasKey("Id");
5011+
5012+
b.ToTable("Parrot", "DefaultSchema");
5013+
});
5014+
5015+
modelBuilder.Entity("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Parrot", b =>
5016+
{
5017+
b.OwnsOne("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Beak", "Child", b1 =>
5018+
{
5019+
b1.Property<int>("ParrotId")
5020+
.HasColumnType("int");
5021+
5022+
b1.Property<string>("Name")
5023+
.HasColumnType("nvarchar(max)");
5024+
5025+
b1.HasKey("ParrotId");
5026+
5027+
b1.ToTable("Parrot", "DefaultSchema");
5028+
5029+
b1.WithOwner()
5030+
.HasForeignKey("ParrotId");
5031+
});
5032+
5033+
b.Navigation("Child");
5034+
});
5035+
"""),
5036+
model =>
5037+
{
5038+
var parentType = model.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Parrot");
5039+
Assert.NotNull(parentType);
5040+
Assert.NotNull(parentType.FindNavigation("Child")!.TargetEntityType);
5041+
5042+
var table = model.GetRelationalModel().Tables.Single();
5043+
Assert.Equal(["Id", "Child_Name", "Name"], table.Columns.Select(t => t.Name));
48925044
});
48935045

48945046
[ConditionalFact]

0 commit comments

Comments
 (0)