2014-04-18 11 views
10

Ich habe mehrere Klassen, die ich von einer gemeinsamen Basisklasse ableiten muss, die eine ID enthält. Das Ignorieren der alle bis auf einen von ihnen für den Augenblick, sagen wir, wir haben:EF6 CodeFirst My [Schlüssel] ID Spalte wird nicht automatisch inkrementiert, da eine Identitätsspalte

public class MyBase { 
    [Key] 
    public int Id { get; set; } 
} 
public class MyName : MyBase { 
    public string Name { get; set; } 
} 

mein Kontext (Datacontext) sieht wie folgt aus:

public DbSet<MyName>MyNames { get; set; } 

// to avoid having EF make a MyBases table and instead map 
// MyBase.Id into MyNames and my other derived classes I do this ... 

protected override void OnModelCreating((DbModelBuilder modelBuilder) { 
    modelBuilder.Entity<MyBase>() 
      .Property(c => c.Id) 
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); 

    modelBuilder.Entity<MyName>() 
      .Map(m => { 
        m.MapInheritedProperties(); 
        m.ToTable("MyNames"); 
       }); 
} 

Der resultierende DB, wenn ich Enable-Migrationen, hinzufügen -Migration Initial und Update-Datenbank ist, dass ich keine Tabelle mit dem Namen MyBases bekommen, sondern erhalte ich die Id-Spalte in Mynames

dbo.MyNames 
    ----------- 
    Id (PK, int, not null) 
    Name (nvarchar(max), null) 

so weit so gut, all das kompiliert und baut, und ich es dann testen verwenden etwa wie folgt:

using (DataContext dc = new DataContext()) { 
     var jj = new MyName { Name = "Janice Joplin" }; 
     dc.MyNames.Add(jj); 
     dc.SaveChanges(); 

     var jh = new MyName { Name = "Jimmy Hendrix" }; 
     dc.MyNames.Add(jh); 
     dc.SaveChanges(); 
    } 

Dies funktioniert beim ersten Mal (Janice hinzugefügt wird mit Id = 0), aber nicht die zweite ... Jimmy bekommt eine DUPLICATE KEY Ausnahme. Anmerkung (für die vollständige Offenlegung) Ich erstelle die jj- und jh-Objekte in einem anderen Teil meines Codes, übergebe sie dann in diese Methode (oben) als MyBase-Objekte und werfe sie dann zurück zu MyName-Objekten, wenn sie das sind. Ich hoffe, das ist kein Problem.

Ich denke, wenn alles in einer Tabelle wäre, könnte die ID als Identität gekennzeichnet werden und @@ IDENTITY könnte verwendet werden, um den Objekt-ID-Wert zuzuweisen. Vielleicht muss ich schließlich eine MyBases-Tabelle erstellen und diesen Datensatz zuerst erstellen und dann die ID in die abgeleiteten Tabellen in einer Transaktion duplizieren. Was ist der beste Ansatz dafür?

Jede Hilfe für diesen EF6 CodeFirst Neuling wäre willkommen. VIELEN DANK.

+0

Können Sie das generierte Schema/DDL? –

Antwort

20

Ich erinnere mich, als ich verwendet EF tun würde ich eine Tabelle mit Identität schaffen und in der Klasse würde ich die id-Spalte mit

[DatabaseGenerated(DatabaseGeneratedOption.Identity)] 

Attribut so gehe ich davon aus, dass Ihr Code sollte

modelBuilder.Entity<MyBase>() 
     .Property(c => c.Id) 
     .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
+0

Dies hatte den gewünschten Effekt, dass die MyBases-Tabelle erstellt wurde. –

+0

Was benutzen Sie jetzt? –

+1

Seltsamerweise musste ich dies für eine Modellklasse tun, aber nicht für die anderen. Ich hasse dich EntityFramework. –

0

Ich glaube, das Problem liegt in der Tatsache, dass Sie EF6 Code First Migrations verwenden. Wenn Sie dies tun, müssen Sie Ihre Datenbank mit der Methode .AddOrUpdate() erstellen. This Stack Overflow Question deckt es ab.