0

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,但是调试器没有到达下一行。

4

2 回答 2

1

问题是s并且dbStudent具有相同的主键。您Teachers.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);});
于 2012-09-09T01:55:12.707 回答
0

我认为你的问题是你的Except陈述。它使用Default比较器比较您的集合项目,当您实际打算比较您的教师对象的值时,比较器会查看项目是否引用内存中的同一对象。

解决方案是提供您自己的IEqualityComparer并准确指定Teacher对象应如何相互比较。MSDN提供了一个很好的例子来说明如何做到这一点。

于 2012-09-08T23:06:16.247 回答