-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
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 existStack 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