0

StudentTeacher私は関係がありmany-to-manyます。

データベースに存在してStudentいて、 new を追加したい場合は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.Count1でもありますが、デバッガーは次の行に到達しません。

4

2 に答える 2

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);});
于 2012-09-09T01:55:12.707 に答える
0

あなたの問題はあなたのExcept発言だと思います。Defaultこれは、実際に Teacher オブジェクトの値を比較しようとしているときに、項目がメモリ内の同じオブジェクトを参照しているかどうかを比較する比較子を使用してコレクション項目を比較しています。

解決策は、独自のものを提供し、オブジェクトを相互に比較するIEqualityComparer方法を正確に指定することです。MSDNは、これを行う方法の良い例を提供します。Teacher

于 2012-09-08T23:06:16.247 に答える