mellis481
mellis481

Reputation: 4148

EF Core “Invalid column name 'Discriminator'” error with inheritance

I have the following entities:

public abstract class Freezer
{
    public int FreezerId { get; set; }
    public string Name { get; set; }
    public int FreezerTypeId { get; set; }
    public int Capacity { get; set; }
}

public class FoodFreezer : Freezer
{
    public List<FoodItem> Foods { get; set; }
}

public class ChemicalFreezer : Freezer
{
    public List<ChemicalItem> Chemicals { get; set; }
}

As you can see the derived Freezer classes do not contain any data that would be stored in the database; they only contain a navigation property of the specific types of contents.

I have the following configurations:

internal class FreezerConfiguration<T> : DbEntityConfiguration<T> where T : Freezer
{
    public override void Configure(EntityTypeBuilder<T> builder)
    {
        builder.ToTable("Freezers");
        builder.HasKey(x => x.FreezerId);

        builder.Property(x => x.FreezerId).IsRequired();
        builder.Property(x => x.Name).IsRequired();
        builder.Property(x => x.FreezerTypeId).IsRequired();
        builder.Property(x => x.Capacity).IsRequired();
    }
}

internal class FoodFreezerConfiguration : FreezerConfiguration<FoodFreezer>
{
    public override void Configure(EntityTypeBuilder<FoodFreezer> builder)
    {
        builder.HasMany(x => x.FoodItems).WithOne(x => x.Freezer);
    }
}

When I make a call to get a list of FoodFreezers from my context, I get a "Invalid column name 'Discriminator'" error. After doing some research, it seems it doesn't like the fact that FoodFreezer and ChemicalFreezer point to a single table. What do I need to change? Do I need a FoodFreezers and ChemicalFreezers database tables with only a FreezerId column that's a FK to the Freezers table?

Upvotes: 6

Views: 7650

Answers (1)

mellis481
mellis481

Reputation: 4148

@haim770 led me down the right path. I had to add the following to my FreezerConfiguration:

builder.HasDiscriminator(x => x.FreezerTypeId)
    .HasValue<FoodFreezer>(FreezerTypeEnum.Food)
    .HasValue<ChemicalFreezer>(FreezerTypeEnum.Chemical);

No additional tables or code needed. If I try to get a FoodFreezer using the ID of a ChemicalFreezer, it returns null. Really cool.

Upvotes: 4

Related Questions