我需要从包含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新手的任何帮助都将不胜感激。谢谢。
答案 0 :(得分:24)
我记得当我以前做EF时我会创建一个带有Identity的表,在类中我会将id列归属于
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
所以我假设你的代码应该是
modelBuilder.Entity<MyBase>()
.Property(c => c.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
答案 1 :(得分:0)
我认为问题在于您使用的是EF6 Code First Migrations。当您这样做时,您需要使用.AddOrUpdate()方法为您的数据库设定种子。 This Stack Overflow Question涵盖了它。