C# 使用EF核心删除范围

C# 使用EF核心删除范围,c#,entity-framework,entity-framework-core,C#,Entity Framework,Entity Framework Core,在单元测试中,使用InMemoryDatabase使用RemoveRange批量删除数据时,我遇到了一个错误 代码如下: public void DeletePatient(Paciente patient) { var schedules = dbContext.Schedules.AsNoTracking().Where(x => x.PatientId == patient.Id).ToList(); dbContext.Schedules.RemoveRange(s

在单元测试中,使用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,直接使用该项会产生相同的错误:

foreach(var item in schedules)
{
    dbContext.Remove(item);
}

尝试删除AsNoTracking子句。我还没有测试过它,但我猜这会导致EF从数据库中重新读取实体,而没有在上下文中找到已经存在的实体。如果没有该条款,它应该找到要删除的上下文中的实际实体。

可能重复@SamiKuhmonen,我使用的是没有事务的InMemoryDatabase。如果您打算进行更改,为什么要使用
AsNoTracking()
?@PanagiotisKanavos,我是EF的新手。我认为只有更新才需要跟踪。这正是你正在做的。更新数据库
AsNoTracking()
仅在您不想进行任何修改时使用,只需加载一些不需要测试的实体即可。跟踪用于启用更改并跟踪用户执行的修改。在没有跟踪的情况下,当调用
SaveChanges
时,EF只会看到它必须保存到数据库中的实体列表