【发布时间】:2017-08-25 15:26:37
【问题描述】:
在我的单元测试中,使用 InMemoryDatabase 使用 RemoveRange 批量删除数据时出现错误。
代码如下:
public void DeletePatient(Paciente patient)
{
var schedules = dbContext.Schedules.AsNoTracking().Where(x => x.PatientId == patient.Id).ToList();
dbContext.Schedules.RemoveRange(schedules);
dbContext.Patients.Remove(patient);
}
这会引发此错误:
InvalidOperationException:无法跟踪实体类型“Schedule”的实例,因为已经在跟踪具有相同键的该类型的另一个实例。添加新实体时,对于大多数键类型,如果未设置键(即,如果键属性为其类型分配了默认值),则会创建一个唯一的临时键值。如果您为新实体显式设置键值,请确保它们不会与现有实体或为其他新实体生成的临时值发生冲突。附加现有实体时,请确保只有一个具有给定键值的实体实例附加到上下文。
但是,如果我执行一次 foreach 并重新加载每个实体,它就会起作用:
foreach(var item in schedules)
{
var h = dbContext.Schedules.Find(item.Id);
dbContext.Remove(h);
}
同样的foreach,直接使用item会报同样的错误:
foreach(var item in schedules)
{
dbContext.Remove(item);
}
【问题讨论】:
-
@SamiKuhmonen,我正在使用 InMemoryDatabase,它没有事务。
-
如果您打算进行更改,为什么要使用
AsNoTracking()? -
@PanagiotisKanavos,我是 EF 的新手。我认为只有更新才需要跟踪。
-
这正是你正在做的。更新数据库。
AsNoTracking()仅在您不想想要进行任何修改时使用,只需加载一些实体
标签: c# entity-framework entity-framework-core