Entity Framework Core - More than one Discriminator for derived classes

c# entity-framework-core entity-framework-core-2.1

Question

I have a model that is structurd as follows (fields ommited for brevity):

public enum ActivityType { Production, Downtime } 
public enum ActivityStatus { Planned Actual }

public abstract class Activity
{
    public virtual ActivityType ActivityType {get;}
    public virtual ActivityStatus ActivityStatus {get;}
}

public abstract class PlannedActivity : Activity
{
    public override ActivityStatus ActivityStatus => ActivityStatus.Planned;
}

public abstract class ActualActivity : Activity
{
    public override ActivityStatus ActivityStatus => ActivityStatus.Actual;
}

Then the concrete 'Entity' classes

public class PlannedDowntime : PlannedActivity
{
    public override ActivityType ActivityType => ActivityType.Downtime;
}
public class PlannedProduction : PlannedActivity
{
    public override ActivityType ActivityType => ActivityType.Production;
}
public class ActualDowntime : ActualActivity
{
    public override ActivityType ActivityType => ActivityType.Downtime;
}
public class ActualProduction : ActualActivity
{
    public override ActivityType ActivityType => ActivityType.Production;
}

I'm trying to save all data to a single database table (i.e. TPH).

In EF6, the following code achieves the database and model structure that I'm looking for:

modelBuilder.Entity<Activity>()
    .Map<PlannedProductionActivity>(m =>
    {
        m.Requires("ActivityType").HasValue("Production");
        m.Requires("ActivityStatus").HasValue("Planned");
    })
    .Map<PlannedDowntimeActivity>(m =>
    {
        m.Requires("ActivityType").HasValue("Downtime");
        m.Requires("ActivityStatus").HasValue("Planned");
    })
    .Map<ActualProductionActivity>(m =>
    {
        m.Requires("ActivityType").HasValue("Production");
        m.Requires("ActivityStatus").HasValue("Actual");
    })
    .Map<ActualDowntimeActivity>(m =>
    {
        m.Requires("ActivityType").HasValue("Downtime");
        m.Requires("ActivityStatus").HasValue("Actual");
    });

But...I need to move this over to EF Core (2.1), and I'm struggling. The following code is the closest I can get, but when migrating it fails with the error 'Every concrete entity type in the hierarchy needs to have a unique discriminator value.

 modelBuilder.Entity<Activity>()
    .HasDiscriminator<ActivityStatus>("ActivityStatus")
    .HasValue<PlannedActivity>(ActivityStatus.Planned)
    .HasValue<ActualActivity>(ActivityStatus.Actual);

modelBuilder.Entity<Activity>()
    .HasDiscriminator<ActivityType>("ActivityType")
    .HasValue<PlannedDowntimeActivity>(ActivityType.Downtime)
    .HasValue<ActualDowntimeActivity>(ActivityType.Downtime)
    .HasValue<PlannedProductionActivity>(ActivityType.Production)
    .HasValue<ActualProductionActivity>(ActivityType.Production);

Please can anyone cast some light on how to have more than one discriminator?

1
3
7/19/2018 4:00:07 PM

Popular Answer

Well, seems a little odd to need two discriminators -

but you could structure it so that Activity has a discriminator and then the sub classes also have their own discriminators

alternatively make a complex discriminator

modelBuilder.Entity<Activity>()
.HasDiscriminator(x=> new {x.ActivityStatus, x.ActivityType})
.HasValue<PlannedDowntimeActivity>(new {ActivityStatus.Planned,ActivityType.Downtime} );

along the lines of above - but with extra values, have a bunch of ones like above throughout our own code base now

2
7/19/2018 4:37:42 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow