Skip to content

TPT: Renaming base & derived type primary key does not work #23444

@ptffr

Description

@ptffr

Problem

EF Core allows us to rename the base type primary key without any errors by doing this

builder.Property(p => p.Id).HasName("referral_pkey");

but trying to update the database will result in an expected There is already an object named 'something_else_pk' in the database error.

Trying to give different names to each derived type will result in

System.InvalidOperationException: A key cannot be configured on 'UserReferral' because it is a derived type. The key must be configured on the root type 'Referral'.

Code / Sample

I created a small sample of this bug https://github.com/keenjus/EFCore5TPTBug

public class Referral
    {
        public Guid Id { get; set; }
    }

    public class UserReferral : Referral
    {
        public string Name { get; set; }
        public string Email { get; set; }
    }

    public class ReferralEntityConfiguration : IEntityTypeConfiguration<Referral>
    {
        public void Configure(EntityTypeBuilder<Referral> builder)
        {
            // This causes all derived classes to use the same key name and PostgreSQL does not like that
            // PostgreSQL error 42P07: relation "referral_pkey" already exists
            builder.HasKey(p => p.Id).HasName("referral_pkey");

            builder.ToTable("referral");
        }
    }

    public class UserReferralEntityConfiguration : IEntityTypeConfiguration<UserReferral>
    {
        public void Configure(EntityTypeBuilder<UserReferral> builder)
        {
            // Trying to change the key name for a derived type will get you this exception
            // System.InvalidOperationException: A key cannot be configured on 'UserReferral' because it is a derived type. The key must be configured on the root type 'Referral'.

            //builder.HasKey(p => p.Id).HasName("user_referral_pkey");

            builder.ToTable("user_referral");
        }
    }


    public class TestDbContext : DbContext
    {
        public DbSet<Referral> Referrals { get; set; }
        public DbSet<UserReferral> UserReferrals { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);

            optionsBuilder.UseNpgsql("Host=localhost;Port=5432;Database=efcore5tptbug;Username=postgres;Password=;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.ApplyConfigurationsFromAssembly(typeof(TestDbContext).Assembly);
        }
    }

Provider and version information

EF Core version: 5.0.0
Database provider: Npgsql.EntityFrameworkCore.PostgreSQL
Target framework: .NET Core 3.1
Operating system: Windows 10
IDE: Visual Studio 2019 16.7.4

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions