2015-10-19 65 views
6

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

我的实体模型:

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

    public int Name { get; set; } 
} 

步骤:

1)我插入这个实体PERSON1的实例(与ID = 1)进我的人表。

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

2)Afters一些加餐我清除整个人表:

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

3)I尝试与相同的主键从第一步骤条目添加条目:PERSON2(具有ID = 1 )

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

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

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

当我添加收拾桌子(具有不同的主键),然后加入从第1步进入后一些其他的入口,它工作正常,这两个项目都保存没有例外。

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

UPDATE: 扩展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"); 
    }  
+0

context.Create(person2) - 这是你自己的方法吗?因为我不记得EF有它。如果是这样 - 你能展示它吗? – Toddams

+0

@Toddams哦,对不起,我将Create方法的主体添加到问题 –

+0

如果从PersonModels中删除所有条目,则可以使用它:'await context.Database.ExecuteSqlCommandAsync(string.Format(“TRUNCATE TABLE'PersonModels' “));'这会对你有用吗? – LocEngineer

回答

0

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

} 
+0

谢谢,但我使用单独的上下文(在我清除Persons表后,我处理上下文并创建用于添加条目的上下文的新实例)。另外,我的((IObjectContextAdapter)ctx).ObjectContext不包含“Persons”(我在我的DbContext实现中只有Persons属性 - >'DbSet Persons',但DbSet没有Detach()。) –

+0

绝对不能在你描述的情况下重现问题。我还更新了'Detach'代码示例。 –