Primärschlüsselverletzung: Vererbung mit EF-Code zuerst

Ich habe folgenden EF-Code als ersten Code. Ich erhalte die folgende Ausnahme:

'GiftCouponPayment' enthält keine Identitätsspalte.

Die Tabellen wurden erfolgreich in der Datenbank erstellt. Wie kann ich diese Ausnahme jedoch beseitigen? Was ist auch der Grund für diese Ausnahme?

Hinweis: Ich bin mit jedem Tabellenschema einverstanden, solange das Domänenmodell (das zuerst mit Code beschrieben wird) beibehalten wird (und die Daten abgefragt werden können).

Nach dem Fortfahren dieser Ausnahme gibt es eine weitere Ausnahme wie folgt:

Beim Speichern von Entitäten, die keine Fremdschlüsseleigenschaften für ihre Beziehungen verfügbar machen, ist ein Fehler aufgetreten. Die EntityEntries-Eigenschaft gibt null zurück, da eine einzelne Entität nicht als Quelle der Ausnahme identifiziert werden kann. Die Behandlung von Ausnahmen beim Speichern kann vereinfacht werden, indem Fremdschlüsseleigenschaften in Ihren Entitätstypen verfügbar gemacht werden. Weitere Informationen finden Sie in der InnerException.

{"Verletzung der PRIMARY KEY-Einschränkung 'PK_dbo.PaymentComponent'. Es kann kein doppelter Schlüssel in Objekt 'dbo.PaymentComponent' eingefügt werden. \ R \ nDie Anweisung wurde abgebrochen."}

Referenz:

Entity Framework: Tabelle in mehrere Tabellen aufteilen

Hinweis: Das resultierende Datenbankschema sieht wie folgt aus.

Code:

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

Antworten auf die Frage(3)

Ihre Antwort auf die Frage