实体框架6和SQLite -不能创建以前删除的PK条目

时间:2022-06-01 20:16:16

I'm using the Entity Framework 6 and the SQLite database (System.Data.SQLite.EF6), but I cannot create an entry with same primary key instantly after deleting it. For example:

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

My model of entity:

我的模型的实体:

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

  public int Name { get; set; }
}

STEPS:

步骤:

1) I insert the instance of this entity person1 (with Id = 1) into my table of persons.

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

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

2) Afters some tome I clear the entire Persons table with:

2)稍等片刻,我把全体人员都清理干净:

using (var context = new MyDbContext())
{
   await context.Database.ExecuteSqlCommandAsync(string.Format("DELETE FROM `PersonModels`"));
   await context.SaveChangesAsync();
}

3) I try to add entry with same primary key as entry from 1st step: person2 (with Id = 1)

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

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

But in 3rd step, SaveChangesAsync() fails with

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

System.InvalidOperationException: The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: Saving or accepting changes failed because more than one entity of type 'DbModels.PersonModel' have the same primary key value.

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

When I add some other entry after clearing the table (with different primary key) and then add entry from 1st step, it works fine and both entries are saved without exceptions.

当我在清理完表(使用不同的主键)之后添加其他条目时,然后从第1步添加条目,它可以正常工作,并且两个条目都可以保存。

I added a breakpoint directly before creating of a new entry (after table is cleared) and checked the Persons table by external tool and table is empty (so there is no entry with id = 1).

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

UPDATE: Extended DbContexte + implementation of my Create method:

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

    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");
    }    

1 个解决方案

#1


0  

EF database contexts maintain a list of objects that it retrieved from the database in-memory until it is destroyed or unloaded.

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();

}

#1


0  

EF database contexts maintain a list of objects that it retrieved from the database in-memory until it is destroyed or unloaded.

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();

}