C# WPF EF6删除实体报IEntityChangeTracker多实例引用错误如何解决?
错误触发原因
这个异常的本质是你要操作的Employe实体对象已经被另一个DbContext实例的IEntityChangeTracker持有跟踪,无法再附加到当前using块内新创建的ScriptBDEntity上下文实例上。
你当前场景下的实体来自ListViewEmployes的绑定数据源,大概率是你在loadlistview方法加载员工列表时,使用了另一个DbContext实例执行查询,且没有关闭查询的自动跟踪功能,导致查出来的所有Employe实体一直被之前的上下文跟踪,此时新上下文尝试Attach同一个实体就会触发冲突。
修复方案
以下3种方案均可解决问题,按需选择即可:
方案1:按主键查询当前上下文实体再删除(最稳妥,无兼容问题)
不直接使用ListView绑定的旧实体,用旧实体的主键在当前上下文查询归属当前上下文的新实体再执行删除,无需手动Attach:
private void btnSupprimer_Click(object sender, RoutedEventArgs e) { var empASupprimer = ListViewEmployes.SelectedItems[0] as Employe; if (empASupprimer == null) { return; } using (var x = new ScriptBDEntity()) { // 注意把此处的Id替换为你Employe实体的实际主键字段名 var empToDelete = x.Employes.Find(empASupprimer.Id); if (empToDelete != null) { x.Employes.Remove(empToDelete); x.SaveChanges(); } loadlistview(); MessageBox.Show("Vous avez supprimer l'employé:" + empASupprimer); } }
方案2:加载列表时关闭实体跟踪
修改loadlistview方法内的查询逻辑,查询时追加AsNoTracking()方法,让查出来的实体不被任何上下文跟踪,原有删除代码不需要改动即可正常运行:
// loadlistview中的查询逻辑示例 using (var x = new ScriptBDEntity()) { // 加AsNoTracking关闭自动跟踪,返回的实体无上下文归属 var empList = x.Employes.AsNoTracking().ToList(); ListViewEmployes.ItemsSource = empList; }
方案3:窗口内复用同一个DbContext实例
WPF桌面应用场景下,你可以在当前窗口的生命周期内维护一个全局的ScriptBDEntity实例,所有查询、删除操作都复用这一个实例,天然不会出现多上下文跟踪冲突的问题,不需要每次操作都新建上下文实例。
内容的提问来源于stack exchange,提问作者Jeremy Simard
相关产品推荐
相关产品推荐

