Pierwotne naruszenie klucza: Dziedziczenie za pomocą kodu EF Najpierw

Mam następujący kod pierwszego kodu EF. Otrzymuję następujący wyjątek:

„GiftCouponPayment” nie zawiera kolumny tożsamości.

Tabele zostały pomyślnie utworzone w bazie danych. Jak jednak pozbyć się tego wyjątku? Jaki jest powód tego wyjątku?

Uwaga: Jestem w porządku z każdym schematem tabeli tak długo, jak długo zachowuje się model domeny (opisany najpierw za pomocą kodu) (a dane mogą być odpytywane).

Po kontynuowaniu tego wyjątku istnieje inny wyjątek, jak poniżej:

Wystąpił błąd podczas zapisywania jednostek, które nie ujawniają właściwości klucza obcego dla ich relacji. Właściwość EntityEntries zwróci wartość null, ponieważ pojedynczej jednostki nie można zidentyfikować jako źródła wyjątku. Obsługa wyjątków podczas zapisywania może być łatwiejsza dzięki ujawnieniu właściwości klucza obcego w typach encji. Szczegółowe informacje można znaleźć w InnerException.

{"Naruszenie ograniczenia PRIMARY KEY 'PK_dbo.PaymentComponent'. Nie można wstawić duplikatu klucza w obiekcie 'dbo.PaymentComponent'. R Instrukcja została zakończona."}

Odniesienie:

Entity Framework: Podziel tabelę na wiele tabel

Uwaga: Wynikowy schemat bazy danych jest przedstawiony poniżej.

Kod:

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; }
}

Klient:

    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();
        }
    }

questionAnswers(3)

yourAnswerToTheQuestion