Skip to content

Commit c486e4f

Browse files
committed
Stop specifying incorrect column name in snapshot for owned type of generic entity type (#32937)
Fixes #32763
1 parent 1b51aa3 commit c486e4f

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/ModelSnapshotSqlServerTest.cs

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,25 @@ public class FooExtension<T>
370370
public T Bar { get; set; }
371371
}
372372

373+
public class Parrot<TChild>
374+
{
375+
public int Id { get; set; }
376+
public string Name { get; set; }
377+
public TChild Child { get; set; }
378+
}
379+
380+
public class Parrot
381+
{
382+
public int Id { get; set; }
383+
public string Name { get; set; }
384+
public Beak Child { get; set; }
385+
}
386+
387+
public class Beak
388+
{
389+
public string Name { get; set; }
390+
}
391+
373392
#region Model
374393

375394
[ConditionalFact]
@@ -4648,6 +4667,139 @@ public virtual void Property_column_name_is_stored_in_snapshot_when_DefaultColum
46484667
var property = entityType.FindProperty("FooExtensionId");
46494668
Assert.NotNull(property);
46504669
Assert.Equal("FooExtension<BarA>Id", property.GetColumnName());
4670+
4671+
Assert.Collection(
4672+
model.GetRelationalModel().Tables,
4673+
t =>
4674+
{
4675+
4676+
Assert.Equal("BarBase", t.Name);
4677+
Assert.Equal(["Id", "Discriminator", "FooExtension<BarA>Id"], t.Columns.Select(t => t.Name));
4678+
},
4679+
t =>
4680+
{
4681+
4682+
Assert.Equal("FooExtension<BarA>", t.Name);
4683+
Assert.Equal(["Id"], t.Columns.Select(t => t.Name));
4684+
});
4685+
});
4686+
4687+
[ConditionalFact]
4688+
public virtual void Generic_entity_type_with_owned_entities()
4689+
=> Test(
4690+
modelBuilder => modelBuilder.Entity<Parrot<Beak>>().OwnsOne(e => e.Child),
4691+
AddBoilerPlate(
4692+
"""
4693+
modelBuilder
4694+
.HasDefaultSchema("DefaultSchema")
4695+
.HasAnnotation("Relational:MaxIdentifierLength", 128);
4696+
4697+
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
4698+
4699+
modelBuilder.Entity("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Parrot<Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Beak>", b =>
4700+
{
4701+
b.Property<int>("Id")
4702+
.ValueGeneratedOnAdd()
4703+
.HasColumnType("int");
4704+
4705+
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
4706+
4707+
b.Property<string>("Name")
4708+
.HasColumnType("nvarchar(max)");
4709+
4710+
b.HasKey("Id");
4711+
4712+
b.ToTable("Parrot<Beak>", "DefaultSchema");
4713+
});
4714+
4715+
modelBuilder.Entity("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Parrot<Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Beak>", b =>
4716+
{
4717+
b.OwnsOne("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Beak", "Child", b1 =>
4718+
{
4719+
b1.Property<int>("ParrotId")
4720+
.HasColumnType("int");
4721+
4722+
b1.Property<string>("Name")
4723+
.HasColumnType("nvarchar(max)");
4724+
4725+
b1.HasKey("ParrotId");
4726+
4727+
b1.ToTable("Parrot<Beak>", "DefaultSchema");
4728+
4729+
b1.WithOwner()
4730+
.HasForeignKey("ParrotId");
4731+
});
4732+
4733+
b.Navigation("Child");
4734+
});
4735+
"""),
4736+
model =>
4737+
{
4738+
var parentType = model.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Parrot<Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Beak>");
4739+
Assert.NotNull(parentType);
4740+
Assert.NotNull(parentType.FindNavigation("Child")!.TargetEntityType);
4741+
4742+
var table = model.GetRelationalModel().Tables.Single();
4743+
Assert.Equal(["Id", "Child_Name", "Name"], table.Columns.Select(t => t.Name));
4744+
});
4745+
4746+
[ConditionalFact]
4747+
public virtual void Non_generic_entity_type_with_owned_entities()
4748+
=> Test(
4749+
modelBuilder => modelBuilder.Entity<Parrot>().OwnsOne(e => e.Child),
4750+
AddBoilerPlate(
4751+
"""
4752+
modelBuilder
4753+
.HasDefaultSchema("DefaultSchema")
4754+
.HasAnnotation("Relational:MaxIdentifierLength", 128);
4755+
4756+
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
4757+
4758+
modelBuilder.Entity("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Parrot", b =>
4759+
{
4760+
b.Property<int>("Id")
4761+
.ValueGeneratedOnAdd()
4762+
.HasColumnType("int");
4763+
4764+
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
4765+
4766+
b.Property<string>("Name")
4767+
.HasColumnType("nvarchar(max)");
4768+
4769+
b.HasKey("Id");
4770+
4771+
b.ToTable("Parrot", "DefaultSchema");
4772+
});
4773+
4774+
modelBuilder.Entity("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Parrot", b =>
4775+
{
4776+
b.OwnsOne("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Beak", "Child", b1 =>
4777+
{
4778+
b1.Property<int>("ParrotId")
4779+
.HasColumnType("int");
4780+
4781+
b1.Property<string>("Name")
4782+
.HasColumnType("nvarchar(max)");
4783+
4784+
b1.HasKey("ParrotId");
4785+
4786+
b1.ToTable("Parrot", "DefaultSchema");
4787+
4788+
b1.WithOwner()
4789+
.HasForeignKey("ParrotId");
4790+
});
4791+
4792+
b.Navigation("Child");
4793+
});
4794+
"""),
4795+
model =>
4796+
{
4797+
var parentType = model.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Parrot");
4798+
Assert.NotNull(parentType);
4799+
Assert.NotNull(parentType.FindNavigation("Child")!.TargetEntityType);
4800+
4801+
var table = model.GetRelationalModel().Tables.Single();
4802+
Assert.Equal(["Id", "Child_Name", "Name"], table.Columns.Select(t => t.Name));
46514803
});
46524804

46534805
[ConditionalFact]

0 commit comments

Comments
 (0)