实体框架6和SQLite -不能创建表项与表项的PK删除之前



我正在使用实体框架6和SQLite数据库(System.Data.SQLite.EF6),但我不能在删除后立即创建具有相同主键的条目。例如:

实体模型:

public class Person
{
  [Key]
  [DatabaseGenerated(DatabaseGeneratedOption.None)]
  public int Id { get; set; }
  public int Name { get; set; }
}

步骤:

1)我将这个实体person1 (Id = 1)的实例插入到我的person表中。

using (var context = new MyDbContext())
{
   context.Create(person1);
   await context.SaveChangesAsync();
}

2)一段时间后,我用:

清除了整个Persons表
using (var context = new MyDbContext())
{
   await context.Database.ExecuteSqlCommandAsync(string.Format("DELETE FROM `PersonModels`"));
   await context.SaveChangesAsync();
}

3)我尝试添加与第一步相同主键的条目:person2(与Id = 1)

using (var context = new MyDbContext())
{
   context.Create(person2);
   await context.SaveChangesAsync();
}

但是在第三步中,SaveChangesAsync()失败了

系统。InvalidOperationException:成功提交了对数据库的更改,但在更新对象上下文时发生了错误。ObjectContext可能处于不一致的状态。内部异常消息:保存或接受更改失败,因为不止一个DbModels类型的实体。

当我在清除表(使用不同的主键)后添加一些其他条目,然后从第一步添加条目时,它工作良好,并且两个条目都被保存,没有异常。

我在创建新条目之前直接添加了一个断点(在表被清除之后),并通过外部工具检查Persons表,表为空(因此没有id = 1的条目)。

更新:扩展dbcontext +实现my Create方法:

    public DbSet<PersonModel> Persons { get; set; }
    public T Create<T>(T entity)
        where T : class
    {
        try
        {
            GetDbSetForType<T>().Add(entity);
            return entity;
        }
        catch (Exception ex)
        {
            return default(T);
        }
    }
    private DbSet<T> GetDbSetForType<T>()
        where T : class
    {
        var type = typeof(T);
        if (type == typeof(PersonModel)) return Persons as DbSet<T>;
        //...my other types
        throw new Exception("Type not found in db");
    }    

EF数据库上下文在内存中维护一个从数据库中检索到的对象列表,直到它被销毁或卸载。

using (var ctx = new MyDbContext())
{
    var person1 = new Person { Id = 1 };
    ctx.Persons.Add(person1);
    await ctx.SaveChangesAsync();
    await context.Database.ExecuteSqlCommandAsync(string.Format("DELETE FROM `PersonModels`"));
    // This is the secret
    ((IObjectContextAdapter)ctx).ObjectContext.Detach(person1);
    ctx.Persons.Add(person1)
    await ctx.SaveChangesAsync();
}

最新更新