新对象,但错误:objectstatemanager中已存在具有相同键的对象。 objectstatemanager无法跟踪多个(...)

时间:2012-09-08 22:24:44

标签: c# entity-framework linq-to-entities many-to-many objectcontext

StudentTeacher是我的关系many-to-many

当我在数据库中存在Student并希望添加新的Teacher时,我会尝试以下代码。

但是符合要求: addedTeachers.ForEach(a => dbStudent.Teacher.Add(a));我收到错误

an object with the same key already exists in the objectstatemanager. the objectstatemanager cannot track multiple objects with the same key”。

怎么了?

void Update(Student s)
{
    using(var context = new MyEntities(connectionString))
    {
        context.ContextOptions.LazyLoadingEnabled = false;
        var dbStudent = context.Student.Include("Teacher").Where(a => a.Id == s.Id).SingleOrDefault();

        var dbTeachers = dbStudent.Teacher.ToList();
        var newTeachers = s.Teacher.ToList();

        var addedTeachers = newTeachers.Except(dbTeachers).ToList();
        var deletedTeachers = dbTeachers.Except(newTeachers).ToList();

        addedTeachers.ForEach(a => dbStudent.Teacher.Add(a));
        deletedTeachers.ForEach(a => dbStudent.Teacher.Remove(a));

        context.SaveChanges();
    }
}

修改

其他奇怪的事情:

在此行之前,异常dbStudent.Teacher.Count为0.但异常为1.当然addedTeachers.Count也是1,但调试器未到达下一行。

2 个答案:

答案 0 :(得分:1)

问题是sdbStudent具有相同的主键。 Teacher集合中的s.Teacher个实例可能会引用s个实例。然后,当您致电addedTeachers.ForEach(a => dbStudent.Teacher.Add(a));时,EF会识别链接到教师实例的所有对象,并尝试添加它们。

尝试

addedTeachers.ForEach(a => { a.Students.Remove(s);
                             a.Students.Add(dbStudent);
                             dbStudent.Teacher.Add(a);});

答案 1 :(得分:0)

我认为您的问题是Except声明。它使用Default比较器比较您的收集项目,比较一下,当您真正打算比较教师对象的值时,查看这些项目是否在内存中引用相同的对象。

解决方案是提供您自己的IEqualityComparer并准确指定Teacher对象应如何相互比较。 MSDN提供了如何执行此操作的一个很好的示例。