6

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?

mellis481
  • 4,332
  • 12
  • 71
  • 118
  • 2
    Seems like you want to achieve a Table-per-Hierarchy (TPH) structure, but you don't seem to use the `HasDiscriminator()` method in your mapping. See https://learn.microsoft.com/en-us/ef/core/modeling/relational/inheritance – haim770 Apr 26 '17 at 16:00

1 Answers1

4

@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.

mellis481
  • 4,332
  • 12
  • 71
  • 118