web-dev-qa-db-fra.com

Le code EF6 d'abord La colonne [Key] Id n'est pas auto-incrémentée, une colonne d'identité devrait

J'ai plusieurs classes dont j'ai besoin pour dériver d'une classe de base commune qui contient un Id. Ignorant tous ces éléments sauf un pour le moment, supposons que nous ayons:

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

mon contexte (DataContext) ressemble à ceci:

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

La base de données résultante, lorsque j'active Enable-Migrations, Add-Migration Initial et Update-Database, est que je ne reçois aucune table appelée MyBases, mais que j'obtiens la colonne Id dans MyNames. 

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

Jusqu'ici tout va bien, tout cela est compilé et construit, puis je le teste en utilisant quelque chose comme:

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

Cela fonctionne la première fois (Janice est ajouté avec Id = 0) mais pas la seconde ... Jimmy obtient une exception DUPLICATE KEY. Remarque (pour une divulgation complète) Je crée en fait les objets jj et jh dans une autre partie de mon code, puis je les passe dans cette méthode (ci-dessus) en tant qu'objets MyBase, puis je les reconvertis en objets MyName s'ils sont comme cela. J'espère que ce n'est pas un problème.

J'imagine que si tout se trouvait dans une seule table, l'identifiant pourrait être marqué Identité et @@ IDENTITY pourrait être utilisé pour affecter la valeur de l'identifiant d'objet. Après tout, je devrais peut-être créer une table MyBases, puis créer d'abord cet enregistrement, puis dupliquer l'ID dans les tables dérivées d'une transaction. Quelle est la meilleure approche pour cela? 

Toute aide pour ce débutant EF6 CodeFirst serait appréciée. MERCI. 

11
Steve L

Je me souviens que lorsque je faisais EF, je créais une table avec Identity et dans la classe, j'attribuais la colonne id avec 

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

donc je suppose que votre code devrait être 

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

Je pense que le problème réside dans le fait que vous utilisez EF6 Code First Migrations. Pour ce faire, vous devez initialiser votre base de données à l’aide de la méthode .AddOrUpdate (). Cette question de débordement de pile la couvre.

0
Chef_Code