C# RemoveRange在实体框架核心中抛出InvalidOperationException

C# RemoveRange在实体框架核心中抛出InvalidOperationException,c#,entity-framework-core,C#,Entity Framework Core,我得到一个错误: 无法跟踪实体类型“瞳孔”的实例,因为另一个 已在跟踪具有相同密钥的此类型的实例。什么时候 添加新实体时,对于大多数键类型,将使用唯一的临时键值 如果未设置密钥(即,如果已分配密钥属性),将创建 其类型的默认值)。如果要显式设置密钥 新实体的值,确保它们不会与现有实体冲突 为其他新实体生成的实体或临时值。什么时候 附加现有实体时,请确保只有一个实体实例具有 给定的键值将附加到上下文 如果我在这个实例加载到上下文缓存之前检索到它,我会理解这个错误,但是我没有 var pup

我得到一个错误:

无法跟踪实体类型“瞳孔”的实例,因为另一个 已在跟踪具有相同密钥的此类型的实例。什么时候 添加新实体时,对于大多数键类型,将使用唯一的临时键值 如果未设置密钥(即,如果已分配密钥属性),将创建 其类型的默认值)。如果要显式设置密钥 新实体的值,确保它们不会与现有实体冲突 为其他新实体生成的实体或临时值。什么时候 附加现有实体时,请确保只有一个实体实例具有 给定的键值将附加到上下文

如果我在这个实例加载到上下文缓存之前检索到它,我会理解这个错误,但是我没有

    var pupilsToDelete = pupilIds.Select(id => new Pupil { Id = id });
    context.RemoveRange(pupilsToDelete.ToList());
    await context.SaveChangesAsync();
在运行时,pupilid都是不同的id


为什么会出现此错误?

要删除记录,需要能够从上下文中进行跟踪。因此,与其创建新的
瞳孔
集合,不如从上下文中引用它们

 var pupilsToDelete = context.Pupils.Where(a => pupilIds.Contains(a.Id)).Select(b => b);
 context.Pupils.RemoveRange(pupilsToDelete);
 await context.SaveChangesAsync();

为了能够删除记录,您需要确保ObjectContext正在跟踪它们。删除项目的最佳方法是@Mostafiz,但您也可以将实体附加到上下文

var pupilsToDelete = pupilIds.Select(id => new Pupil { Id = id });
foreach(var p in pupilsToDelete )
   context.Attach(p);
context.RemoveRange(pupilsToDelete.ToList());
await context.SaveChangesAsync();

这不是一个好方法——

这段代码毫无意义,甚至无法编译;-)将.Select()替换为.Where()。让我们从这里开始。为什么不编译您的表名
studiors
?你正试图从中删除条目?是的,我知道了,现在好了,现在检查一下,这是一个错误代码正常工作,但为什么?RemoveRange是否只删除跟踪的实例?在代码中,您正在创建一个新的RUPIL集合,它实际上不是来自数据库实例。您需要获取要删除的记录的实例是否100%确定未加载
s?
pupilIds
来自哪里?你们有新的上下文实例吗?学生不是从数据库加载的。我还尝试了context.entry(new studio(id=id).state=state.Deleted)并执行了与EF6类似的context.savechanges(),但也导致了异常…顺便说一句,存在context.AttachRange(pupilsToDelete)…当我运行你的代码时,我在RemoveRange遇到了一个异常…似乎我在这里遇到了一个错误…我从未尝试过,但听说它很慢。在实体框架文档中,你可以阅读RemoveRange函数描述以及他们建议如何使用它。附加也没有更好的方法,因为它需要找到所有的id.context.AttachRange(pupilsToDelete)也是trowing bug?是的,它确实抛出异常!