DbSet.Attach尝试为生成的标识列插入显式值

时间:2017-05-24 19:57:46

标签: c# entity-framework entity-framework-core

我有以下课程:

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之后?

1 个答案:

答案 0 :(得分:1)

这是EF中的一种设计行为。 如果调用Add(),则表示该对象不存在于数据库中,因此会为该实体生成密钥。 如果调用Attach(),则表示它存在于db中,因此即使您将状态设置为稍后添加,也不会执行密钥生成。