一尘不染

EF6 CodeFirst我的[Key] Id列不会自动增加,因为Identity列应该

sql

我有几个类需要从包含Id的通用基类派生。暂时忽略其中之一,让我们说:

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

我的上下文(DataContext)看起来像这样:

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

当我启用迁移,初始添加迁移和更新数据库时,生成的数据库是我没有得到名为MyBases的表,而是得到了MyNames中的Id列。

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

到目前为止,所有这些都可以编译和构建,然后使用以下类似代码对其进行测试:

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

第一次有效(Janice的Id = 0添加),但第二次 无效 。…Jimmy获得了DUPLICATE
KEY异常。注意(为全面披露),我实际上是在代码的另一部分中创建jj和jh对象,然后将它们作为MyBase对象传递到该方法中(上面),然后将它们强制转换回MyName对象。我希望这不是问题。

我想如果所有内容都在一个表中,则ID可以标记为Identity,而@@
IDENTITY可以用于分配对象ID值。也许我毕竟需要制作一个MyBases表,并首先创建该记录,然后将Id复制到事务中的派生表中。最好的方法是什么?

此EF6 CodeFirst新手的任何帮助将不胜感激。谢谢。


阅读 174

收藏
2021-03-17

共1个答案

一尘不染

我记得当我以前做过EF时,我会用Identity创建一个表,并在该类中将id列赋给

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

所以我假设你的代码应该是

   modelBuilder.Entity<MyBase>()
        .Property(c => c.Id)
        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
2021-03-17