C# 实体框架6和SQLite-无法创建条目PK之前已删除的条目

C# 实体框架6和SQLite-无法创建条目PK之前已删除的条目,c#,database,entity-framework,sqlite,C#,Database,Entity Framework,Sqlite,我使用的是EntityFramework6和SQLite数据库(System.Data.SQLite.EF6),但我无法在删除条目后立即创建具有相同主键的条目。例如: 我的实体模型: public class Person { [Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; } public int Name { get; set; } } 步骤: 1) 我将这

我使用的是EntityFramework6和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)的实例插入到我的persons表中

using (var context = new MyDbContext())
{
   context.Create(person1);
   await context.SaveChangesAsync();
}
2) 几分钟后,我用以下方法清除整个人员表:

using (var context = new MyDbContext())
{
   await context.Database.ExecuteSqlCommandAsync(string.Format("DELETE FROM `PersonModels`"));
   await context.SaveChangesAsync();
}
3) 我尝试添加与第一步中的条目主键相同的条目:person2(Id=1)

但在第三步中,
savechangesync()
失败

System.InvalidOperationException:已成功提交对数据库的更改,但更新对象上下文时出错。ObjectContext可能处于不一致的状态。内部异常消息:保存或接受更改失败,因为“DbModels.PersonModel”类型的多个实体具有相同的主键值

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

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

更新: 我的创建方法的扩展DbContexte+实现:

    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");
    }    
public DbSet Persons{get;set;}
公共T创建(T实体)
T:在哪里上课
{
尝试
{
GetDbSetForType().Add(实体);
返回实体;
}
捕获(例外情况除外)
{
返回默认值(T);
}
}
私有DbSet GetDbSetForType()
T:在哪里上课
{
var类型=类型(T);
if(type==typeof(PersonModel))将Persons作为DbSet返回;
//…我的其他类型
抛出新异常(“在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();

}

Create(person2)-这是您自己的方法吗?因为我不记得EF有。如果是,你能展示它吗?@Toddams哦,对不起,我在问题中添加了我的Create方法的主体。如果你删除PersonModels中的所有条目,你可以改为使用:
wait context.Database.ExecuteSqlCommandAsync(string.Format(“TRUNCATE TABLE'PersonModels')
这对您有用吗?@LocEngineer SQLite不支持TRUNCATE命令(来自官方文档:很遗憾,SQLite中没有TRUNCATE TABLE命令,但您可以使用SQLite DELETE命令删除现有表中的完整数据。)太糟糕了。但是,根据您的要求,可以通过在事务中运行delete命令并提交该事务来解决此问题。谢谢,但我使用的是单独的上下文(在清除Persons表后,我会释放上下文并创建一个新的上下文实例以添加条目)。另外,my((IObjectContextAdapter)ctx).ObjectContext不包含“Persons”(我在DbContext->
DbSet Persons的实现中只有Persons属性,但DbSet没有Detach()),在您描述的情况下,我肯定无法重现该问题。我还更新了
Detach
代码示例。
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();

}