Violación de la clave principal: herencia utilizando primero el código EF

Tengo el siguiente código de código de EF. Estoy recibiendo la siguiente excepción:

'GiftCouponPayment' no contiene una columna de identidad.

Las tablas se crean con éxito en la base de datos. Sin embargo, ¿cómo puedo deshacerme de esta excepción? Además, ¿cuál es la razón de esta excepción?

Nota: Estoy de acuerdo con cualquier esquema de tabla tan largo como se retenga el modelo de dominio (descrito usando el código primero) (y se pueden consultar los datos).

Después de continuar con esta excepción, hay otra excepción como la siguiente:

Se produjo un error al guardar entidades que no exponen propiedades de clave externa para sus relaciones. La propiedad EntityEntries devolverá un valor nulo porque una sola entidad no puede identificarse como el origen de la excepción. El manejo de las excepciones al guardar se puede hacer más fácil al exponer las propiedades de clave externa en sus tipos de entidad. Vea la InnerException para más detalles.

{"Violación de la restricción PRIMARY KEY 'PK_dbo.PaymentComponent'. No se puede insertar una clave duplicada en el objeto 'dbo.PaymentComponent'. \ R \ nLa declaración se ha terminado."}

Referencia:

Entity Framework: dividir tabla en tablas múltiples

Nota: El esquema de base de datos resultante es como se muestra a continuación.

Código:

public class MyInitializer : CreateDatabaseIfNotExists<NerdDinners>
{
    //Only one identity column can be created per table.
    protected override void Seed(NerdDinners context)
    {
        //context.Database.ExecuteSqlCommand("CREATE UNIQUE INDEX IX_Payment_PayedTime ON Payment (PayedTime)");
        context.Database.ExecuteSqlCommand("DBCC CHECKIDENT ('Payment', RESEED, 1)");
        context.Database.ExecuteSqlCommand("DBCC CHECKIDENT ('GiftCouponPayment', RESEED, 2)");
        context.Database.ExecuteSqlCommand("DBCC CHECKIDENT ('ClubCardPayment', RESEED, 3)");
    }
}

//System.Data.Entity.DbContext is from EntityFramework.dll
public class NerdDinners : System.Data.Entity.DbContext
{
    public NerdDinners(string connString): base(connString)
    { 
    }

    protected override void OnModelCreating(DbModelBuilder modelbuilder)
    {
        //Fluent API - Plural Removal
        modelbuilder.Conventions.Remove<PluralizingTableNameConvention>();

        //Fluent API - Table per Concrete Type (TPC)
        modelbuilder.Entity<GiftCouponPayment>()
            .Map(m =>
            {
                m.MapInheritedProperties();
                m.ToTable("GiftCouponPayment");
            });

        modelbuilder.Entity<ClubCardPayment>()
            .Map(m =>
            {
                m.MapInheritedProperties();
                m.ToTable("ClubCardPayment");
            });
    }

    public DbSet<GiftCouponPayment> GiftCouponPayments { get; set; }
    public DbSet<ClubCardPayment> ClubCardPayments { get; set; }
    public DbSet<Payment> Payments { get; set; }
}

public abstract class PaymentComponent
{
    public int PaymentComponentID { get; set; }
    public int MyValue { get; set; }
    public abstract int GetEffectiveValue();
}

public partial class GiftCouponPayment : PaymentComponent
{
    public override int GetEffectiveValue()
    {
        if (MyValue < 2000)
        {
            return 0;
        }
        return MyValue;
    }
}

public partial class ClubCardPayment : PaymentComponent
{
    public override int GetEffectiveValue()
    {
        return MyValue;
    }
}

public partial class Payment
{
    public int PaymentID { get; set; }
    public List<PaymentComponent> PaymentComponents { get; set; }
    public DateTime PayedTime { get; set; }
}

Cliente:

    static void Main(string[] args)
    {
        Database.SetInitializer<NerdDinners>(new MyInitializer());
        string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30";

        using (var db = new NerdDinners(connectionstring))
        {
            GiftCouponPayment giftCouponPayment = new GiftCouponPayment();
            giftCouponPayment.MyValue=250;

            ClubCardPayment clubCardPayment = new ClubCardPayment();
            clubCardPayment.MyValue = 5000;

            List<PaymentComponent> comps = new List<PaymentComponent>();
            comps.Add(giftCouponPayment);
            comps.Add(clubCardPayment);

            var payment = new Payment { PaymentComponents = comps, PayedTime=DateTime.Now };
            db.Payments.Add(payment);

            int recordsAffected = db.SaveChanges();
        }
    }

Respuestas a la pregunta(3)

Su respuesta a la pregunta