efcore / EFCore.NamingConventions

Entity Framework Core plugin to apply naming conventions to table and column names (e.g. snake_case)
Apache License 2.0
759 stars 75 forks source link

TPT table names are not being rewritten with UseTptMappingStrategy() #201

Closed senketsu03 closed 10 months ago

senketsu03 commented 1 year ago

Repro code:

public class Student
{
    public int Id { get; set; }

    public string? Name { get; set; }
}

public class HonoredStudent : Student
{
    public string Award { get; set; }
}

public class ApplicationContext : DbContext
{
    public DbSet<Student> Students { get; set; } = null!;

    public DbSet<HonoredStudent> HonoredStudents { get; set; } = null!;

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Student>().UseTptMappingStrategy();
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Data Source=../students.db")
                      .UseSnakeCaseNamingConvention();
    }
}

This creates two tables: Students and HonoredStudents. Expected them to be named students and honored_students correspondingly. Of course I can force these names, using TableAttribute, but that's not the desired behavior

maftieu commented 1 year ago

I have the same issue.

When applying snake_casing on tables with TPT (with UseTptMappingStrategy()), table names and PK constaint names are not transformed into snake case.

Not a blocking issue, because I can rewrite table names. But with custom table names, PK names are labeled "PK_my_custom_table_name" (PK is uppercased).

public abstract class Person
{
    public int Id { get; set; }
    // ...
}
public class Candidate : Person
{
    // ...
}
public class Juror : Person
{
    // ...
}

EF entity configuration

builder.Entity<Person>().UseTptMappingStrategy();
// nothing for the inherited `Candidate` and `Juror` entities

What is generated

migrationBuilder.CreateTable(
    name: "Persons",                                        // !! not in lowercase
    schema: "persons",
    columns: table => new
    {
        id = table.Column<Guid>(type: "uuid", nullable: false),
        // ...
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_Persons", x => x.id);          // !! not in lowercase
    });

migrationBuilder.CreateTable(
    name: "Candidates",                                     // !! not in lowercase
    schema: "persons",
    columns: table => new
    {
        id = table.Column<Guid>(type: "uuid", nullable: false),
        // ...
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_Candidates", x => x.id);       // !! not in lowercase
        table.ForeignKey(
            name: "fk_candidates_persons_id",
            column: x => x.id,
            principalSchema: "persons",
            principalTable: "Persons",
            principalColumn: "id",
            onDelete: ReferentialAction.Cascade);
    });

migrationBuilder.CreateTable(
    name: "Jurors",                                         // !! not in lowercase
    schema: "persons",
    columns: table => new
    {
        id = table.Column<Guid>(type: "uuid", nullable: false),
        // ...
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_Jurors", x => x.id);           // !! not in lowercase
        table.ForeignKey(
            name: "fk_jurors_persons_id",
            column: x => x.id,
            principalSchema: "persons",
            principalTable: "Persons",
            principalColumn: "id",
            onDelete: ReferentialAction.Cascade);
    });

For other tables in my db context, the pk and table names are correctly snake cased.

Versions

sebdesalvador commented 1 year ago

Same issue here :(

roji commented 10 months ago

Sorry for taking so long to investigate this. I can indeed reproduce the issue and have pushed a fix for 8.0.0, which is about to get released.

On 7.0, this can be worked around by setting the table names explicitly instead of using UseTptMappingStrategy:

protected override void OnModelCreating(ModelBuilder modelBuilder)  
{  
    modelBuilder.Entity<Student>().ToTable("students");  
    modelBuilder.Entity<Student>().ToTable("honored_students");
    modelBuilder.Entity<Student>().UseTptMappingStrategy();  
}
Gigas002 commented 10 months ago

Hello, @roji! Thank you for working on this! I've tested last versions, the 8.0.1 works fine (tables students and honored_students are created), but on 8.0.2 there are Students and honored_students are created.

roji commented 10 months ago

@Gigas002 thanks for flagging this, opened #259 to fix for 8.0.3.