New object, but error: an object with the same key already exists in the objectstatemanager. the objectstatemanager cannot track multiple (…)

StackOverflow https://stackoverflow.com/questions/12334968

Question

Student and Teacher are i relationship many-to-many.

When I have Student existed in database, and want to add new Teacher, I try code below.

But in line: addedTeachers.ForEach(a => dbStudent.Teacher.Add(a)); I get error

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

What's wrong?

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();
    }
}

EDIT

What's strange else:

just before this line with exception dbStudent.Teacher.Count is 0. But after exception is 1. Of course addedTeachers.Count is also 1, but debugger doesn't reach the next line.

Was it helpful?

Solution

The problem is s and dbStudent has the same primary key. Your Teacher instances in s.Teacher collection may refer to the s instance. Then when you call addedTeachers.ForEach(a => dbStudent.Teacher.Add(a));, EF will identity all objects linked to teacher instance and try to add them too.

Try

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

OTHER TIPS

I think your problem is your Except statement. It is comparing your collection items using the Default comparer which is comparing to see if the items reference the same object in memory when you actually intend it to compare the values of your Teacher objects.

The solution is to provide your own IEqualityComparer and specify exactly how the Teacher objects should be compared to each other. MSDN provides a good example of how to do this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top