C# 实体框架6和SQLite-无法创建条目PK之前已删除的条目
我使用的是EntityFramework6和SQLite数据库(System.Data.SQLite.EF6),但我无法在删除条目后立即创建具有相同主键的条目。例如: 我的实体模型: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) 我将这
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();
}