Skip to content

TPH Inheritance with Relationship in the Parent Object doesn't like Sharing Foreign Key #35870

@apla1297

Description

@apla1297

Question

I'm having trouble properly configuring inheritance for EF. I'm following TPH Pattern, however the kicker seems to be the shared foreign key in the base class.

I have a Base class Module and then a number of different types of modules that inherit from the abstract base. The base class has a property of type collaborator which is another class and a separate table in the database. Each of the child inherited types have a relationship to a collaborator thus each one would have that same Foreign Key "CollabroatorId". Because i want the ability to get each of the different types of modules off the collaborator I've configured multiple one to many relationships from collaborator back to Module. Each relationship is using the same foreign key. However, When I go to make queries EF is creating shadow foreign key names like "ModuleA_CollaboratorId" and because this column doesn't exist the whole thing blows up. How to i strictly enforce the foreign key to be CollaboratorId so they all share the same column?

Your code

internal class ModuleConfiguration : IEntityTypeConfiguration<Module>
{
    public void Configure(EntityTypeBuilder<Module> modelBuilder)
    {
        modelBuilder.ToTable("Modules", "core");

        //Omitted other mappings for brevity

        modelBuilder.HasDiscriminator<string>("ModuleType")
            .HasValue<AudioModule>("ModuleA")
            .HasValue<SfxModule>("ModuleB");
    }
}

internal class CollaboratorConfiguration : IEntityTypeConfiguration<Collaborator>
{
    public void Configure(EntityTypeBuilder<Collaborator> modelBuilder)
    {
        modelBuilder.ToTable("Collaborators", "core");

        //Omitted other mappings for brevity

        modelBuilder
            .HasMany(collaborator => collaborator.ModuleA)
            .WithOne(moduleA => moduleA.Collaborator)
            .HasForeignKey("CollaboratorId");

        modelBuilder
            .HasMany(collaborator => collaborator.ModuleB)
            .WithOne(moduleB => moduleB.Collaborator)
            .HasForeignKey("CollaboratorId");
    }
}

//Omitting configuration for ModuleA and ModuleB for brevity, all they do is mp the Content field to the JSON


    public abstract class Module
    {
        //Omitted other properties for brevity
        public int Id { get; set; }
        public Collaborator Collaborator { get; set; }
        public Module() { }

        public Module(Collaborator collab)
        {
            Collaborator = collab;
        }

    }


public class ModuleA : Module
{
    public ModAContent Content { get; set; }


    private ModuleA() { }
    public ModuleA(Collaborator collab) : base(collab)
    {
        Content = new Content(collab);
    }
}

public class ModuleB : Module
{
    public ModBContent Content { get; set; }


    private ModuleB() { }
    public ModuleB(Collaborator collab) : base(collab)
    {
        Content = new Content(collab);
    }
}

public class Collaborator
{
    public int Id { get; set; }
    public List<ModuleA> ModuleA { get; set; }
    public List<ModuleB> ModuleB { get; set; }

    private Collaborator() { }
    public Collaborator()
    {
        ModuleA = new List<ModuleA>();
        ModuleB = new List<ModuleB>();
    }
}


Querying the database

var collab = await _context.Collaborators.Include(c => c.ModuleB).ToList(); 

When I try to query the database, I get the following error: 

PostgresException: 42703: column m.ModuleB_CollaboratorId does not exist

Stack traces

Querying the database

var collab = await _context.Collaborators.Include(c => c.ModuleB).ToList(); 

When I try to query the database, I get the following error: 

PostgresException: 42703: column m.ModuleB_CollaboratorId does not exist

Verbose output

Querying the database

var collab = await _context.Collaborators.Include(c => c.ModuleB).ToList(); 

When I try to query the database, I get the following error: 

PostgresException: 42703: column m.ModuleB_CollaboratorId does not exist

EF Core version

9.0.0

Database provider

Npgsql.EntityFrameworkCore.PostgreSQL

Target framework

.Net 9.0

Operating system

Windows 11

IDE

Visual Studio 2022 AND LinqPad 8

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