EFCore.NamingConventions: Regression in 7.0.2: TPH table names are not being rewritten
When using TPH, table name is not being rewritten - following example creates tables blogs (correct) and Posts (incorrect). This behavior was correct in version 7.0.0
Repro:
using Microsoft.EntityFrameworkCore;
class Blog
{
public int Id { get; set; }
public ICollection<Post> Posts { get; set; }
}
abstract class Post
{
public int Id { get; set; }
public Blog Blog { get; set; }
public int Blog_Id { get; set; }
}
class InternalPost : Post { }
class ExternalPost : Post { }
class TestContext : DbContext
{
public DbSet<Blog> Blogs { get; set; } = null!;
public DbSet<Post> Posts { get; set; } = null!;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.UseNpgsql("Server=localhost;Database=testefnamingconventions_local;User Id=postgres;Password=root;");
optionsBuilder.UseLowerCaseNamingConvention();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Blog>().HasMany(x => x.Posts).WithOne(x => x.Blog).HasForeignKey(x => x.Blog_Id);
modelBuilder.Entity<Post>().HasOne(x => x.Blog).WithMany(x => x.Posts).HasForeignKey(x => x.Blog_Id);
modelBuilder.Entity<InternalPost>();
modelBuilder.Entity<ExternalPost>();
}
}
Generated migration:
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace testefnamingconventions.Migrations
{
/// <inheritdoc />
public partial class InitialStructure : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "blogs",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
},
constraints: table =>
{
table.PrimaryKey("pk_blogs", x => x.id);
});
migrationBuilder.CreateTable(
name: "Posts",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
blogid = table.Column<int>(name: "blog_id", type: "integer", nullable: false),
discriminator = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_posts", x => x.id);
table.ForeignKey(
name: "fk_posts_blogs_blogid",
column: x => x.blogid,
principalTable: "blogs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "ix_posts_blog_id",
table: "Posts",
column: "blog_id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Posts");
migrationBuilder.DropTable(
name: "blogs");
}
}
}
btw: Thank you for quickly solving #179 ❤️
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 11
- Comments: 18 (6 by maintainers)
Commits related to this issue
- fix "Regression in 7.0.2: TPH table names are not being rewritten" fix #184 — committed to erwan-joly/EFCore.NamingConventions by erwan-joly a year ago
- fix "Regression in 7.0.2: TPH table names are not being rewritten" fix #184 — committed to erwan-joly/EFCore.NamingConventions by erwan-joly a year ago
- fix "Regression in 7.0.2: TPH table names are not being rewritten" fix #184 — committed to erwan-joly/EFCore.NamingConventions by erwan-joly a year ago
- fix "Regression in 7.0.2: TPH table names are not being rewritten" fix #184 — committed to erwan-joly/EFCore.NamingConventions by erwan-joly a year ago
- fix "Regression in 7.0.2: TPH table names are not being rewritten" fix #184 — committed to erwan-joly/EFCore.NamingConventions by erwan-joly a year ago
- Redo management of table name in hierarchies * Trigger common logic when: 1. A new entity type is added 2. The base type of an entity type changes 3. The hierarchy mapping strategy changes * Th... — committed to roji/EFCore.NamingConventions by roji 6 months ago
- Redo management of table name in hierarchies (#239) * Trigger common logic when: 1. A new entity type is added 2. The base type of an entity type changes 3. The hierarchy mapping strategy ch... — committed to efcore/EFCore.NamingConventions by roji 6 months ago
@at-besa I unfortnuately simply haven’t had any time in recent months to work on this plugin… In a few weeks I should be able to set aside a day or two for 8.0 preparation, I’ll try to also do the pending 7.0 work as well (like this PR).
Sorry about this, I’ll take a look as soon as I can.
If you need to update to 7.0.2 now there is simple workaround - manually map affected entities to their tables (see below) as everything else seem to be rewritten properly. It is enough to set the name on your TPH root entities.
@xamir82 did you see the really easy workaround above by @Kukkimonsuta ? This issue should not block you from moving to .net8.
Thanks @erwan-joly, I do agree that this is a blocking regression; I may not have time to do considerable work on this plugin, but I do intend to at least fix this before releasing the official 8.0.0.
Once I finish with more things urgent (like releasing Npgsql and EFCore.PG 8.0.0), I’ll take a look here.
@aradalvand I’ll try to find some time for this plugin, but right at the moment there’s simply too much going on.
@roji are you gonna allow that PR before .net 8? 7.0.2 was released in january and this still affects several projects.
@UliPlabst Thank you for pointing that out, I didn’t see it before actually. Good to know.
Update: Lol now #234 is blocking me!
@xamir82 EFCore.PG was released yesterday night - I do intend to fix this regression in the coming weeks and then publish EFCore.NamingConventions 8.0, but you’ll have to be a bit more patient.
@roji not too sure as I did not test it but wouldn’t this be the issue ? If i understand correctly we prevent naming of abstract class to apply. https://github.com/efcore/EFCore.NamingConventions/commit/8ce1fb1bb043bc8d6b360ef11da9efbf74c1ee72#diff-340b0b728e82bffdba8e561a04c249bbe989fd2e0ccfe93ac0906191a70af34aL63
I believe you want to prevent abstract class only in case of TPC
if (entityType.GetTableName() is { } tableName && (entityType.GetMappingStrategy() != RelationalAnnotationNames.TpcMappingStrategy || !entityType.ClrType.IsAbstract))