EF Core TPH Migration - Derived types have no key defined

325 Views Asked by At

EF migrations fails and tells me that the derived types have no key defined.

I'm trying to setup TPH, which should be fairly easy with attributes, but I can't get it to work with separate (fluent-)configuration files. It always reports that the key of the derived types is not defined.

If I define it on the derived types, then it says the key must be defined for the base type.

Entity type configurations:

public class CoreEntityConfiguration<TBaseModel> : IEntityTypeConfiguration<TBaseModel> where TBaseModel : class, ICoreEntity
{
    public virtual void Configure(EntityTypeBuilder<TBaseModel> builder)
    {
        builder.Property(p => p.Created).IsDateColumn().HasDefaultValueSql("GETDATE()").ValueGeneratedOnAdd();
        builder.Property(p => p.Modified).IsDateColumn().HasDefaultValueSql("GETDATE()").ValueGeneratedOnAddOrUpdate();
        builder.Property(p => p.Rowversion).IsRowVersion();
    }
}

public class BaseEntityConfiguration<TBaseEntity, TKey> : CoreEntityConfiguration<TBaseEntity> where TBaseEntity : BaseEntity<TKey>
{
    public override void Configure(EntityTypeBuilder<TBaseEntity> builder)
    {
        base.Configure(builder);
        builder.HasKey(p => p.ID);
    }
}

public class EventConfiguration : BaseEntityConfiguration<Event, int>
{
    public override void Configure(EntityTypeBuilder<Event> builder)
    {
        base.Configure(builder);

        builder.ApplyConfiguration(new SearchableConfiguration<Event, int>());

        builder.Property(p => p.Time).IsDateTimeOffsetColumn();

        builder.HasOne(p => p.Player).WithMany(p => p.Events).HasForeignKey(p => p.PlayerID).OnDelete(Microsoft.EntityFrameworkCore.DeleteBehavior.Restrict);

        builder.HasDiscriminator(p => p.EventType)
            .HasValue<Goal>("Goal")
            .HasValue<Card>("Card")
            .HasValue<Substitution>("Substitution");

        builder.ToTableWithSchema(Constants.SCHEME_OPERATIONS);
    }
}

public class EventGoalConfiguration : IEntityTypeConfiguration<Goal>
{
    public void Configure(EntityTypeBuilder<Goal> builder)
    {
        builder.HasBaseType<Event>();

        builder.HasOne(p => p.GoalType).WithMany().OnDelete(DeleteBehavior.Restrict);
        builder.HasOne(p => p.AssistedByPlayer).WithMany(p => p.Assists).HasForeignKey(p => p.AssistedByPlayerID).OnDelete(DeleteBehavior.SetNull);
    }
}

Model classes:

public abstract class CoreEntity : ICoreEntity
{
    public DateTime Created { get; set; }
    public int CreatedByID { get; set; }
    public DateTime? Modified { get; set; }
    public int? ModifiedByID { get; set; }
    public byte[] Rowversion { get; set; }
}

public abstract class BaseEntity<TKey> : CoreEntity, IBaseEntity<TKey>
{
    public TKey ID { get; set; }
}

public abstract class Event : BaseEntity<int>
{
    ...
}

public class Goal : Event
{
    public int GoalTypeID { get; set; }
    public virtual GoalType GoalType { get; set; }

    public int? AssistedByPlayerID { get; set; }
    public virtual Player AssistedByPlayer { get; set; }
}

I can't get rid of this error:

Migration error

Please help me and tell me what I am doing wrong. I can't seem to figure it out...

0

There are 0 best solutions below