我有以下课程:
public class MyEntity
{
public int Id { get; set; }
}
public class MyContext : DbContext
{
public MyContext(DbContextOptions<MyContext> options) : base(options) { }
public DbSet<MyEntity> MyEntities { get; set; }
}
然后在另一个班级中我运行以下内容:
var entity = new MyEntity();
myContext.MyEntities.Attach(entity).State = EntityState.Added;
myContext.SaveChanges();
对SaveChanges的调用抛出了异常:
当IDENTITY_INSERT设置为OFF时,无法在表MyEntity中为identity列插入显式值
此时我的模式完全按照约定创建,Id列应该是自动生成的。该问题似乎与我使用Attach
并手动设置EntityState.Added
有关。当我改为使用Add
时:
myContext.MyEntities.Add(entity);
它运作得很好。但是,我想使用Attach
因为在我的真实场景中MyEntity
将具有数据库中已存在的未跟踪的子属性。 Add
会自动将相关未跟踪实体的状态设置为EntityState.Added
,我不想手动将这些现有实体的状态设置为EntityState.Unchanged
。
我在这里缺少什么?为什么EF尝试插入显式标识值,即使在附加实体并将其状态设置为Added
之后?
答案 0 :(得分:1)
这是EF中的一种设计行为。 如果调用Add(),则表示该对象不存在于数据库中,因此会为该实体生成密钥。 如果调用Attach(),则表示它存在于db中,因此即使您将状态设置为稍后添加,也不会执行密钥生成。