EF6 CodeFirst My [Key] Id Column is not auto-incrementing as an identity column should

c# code-first entity-framework on-duplicate-key sql

Question

I need to derivate a number of classes from a base class that shares an Id. For the time being, let's say we ignore all but one of these.

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

My context (DataContext) appears to be as follows:

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

When I enable migrations, add the initial migration, then update the database, I don't get the MyBases table; instead, I get the Id field in MyNames.

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

So far, so good. Everything builds and compiles, and I test it using something like this:

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

When adding Jane with Id = 0, it works the first time, but Jimmy encounters a DUPLICATE KEY exception the second time. For the sake of full disclosure, please take note that I really created the jj and jh objects in a different section of my code, passed them into the method above as MyBase objects, and then, if necessary, converted them back to MyName objects. I'm hoping that won't be an issue.

I suppose if everything were in a single table, the Id could be set to Identity and the object Id value could be assigned using @@IDENTITY. Maybe I will need to generate the entry first in a MyBases table, then duplicate it into the derived tables in a transaction. What's the best course of action here?

This EF6 CodeFirst beginner would appreciate any assistance. THANKS.

1
14
4/18/2014 4:47:54 AM

Accepted Answer

When I first started using EF, I recall making a table using Identity and assigning the id column to the class.

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

hence, I believe that your code should be

   modelBuilder.Entity<MyBase>()
        .Property(c => c.Id)
        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
27
4/18/2014 5:17:17 AM

Popular Answer

ZZZ_tmp


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow