5

関連するエンティティのコレクションを更新する際に問題が発生しています。

本質的に問題は次のとおりです。

public class Student
{
    public virtual ICollection<Lecture> Lectures { get; set; }

    public void AddLecture(Lecture lecture)
    {
        Lectures.Add(lecture);
    }

    public void CancelChanges()
    {
        _context.Refresh(RefreshMode.StoreWins, this);
        _context.LoadProperty(this, (o) => o.Lectures, 
            MergeOption.OverwriteChanges);
    }
}

public class Grade
{
    public virtual Student { get; set; }
}

これで、レクチャーを追加するための GUI ができました。必要に応じて、編集プロセスをキャンセルできます。

public void ExampleEdit()
{
    Student student = _context.Students.SingleOrDefault(/* blah */);
    student.AddLecture(_context.Lectures.SingleOrDefault(/* e.g. math */));
    student.CancelChanges();
    // At this point student SHOULD have no lectures anymore since the 
    // property was loaded with overwrite changes option.
    // Yet the Lectures still contains the lecture we added there
}

それで、コードは悪いですか?間違って使用する方法はありますか? オブジェクト全体を完全にリロードすることは可能ですか?..

4

1 に答える 1

7

MergeOption.OverwriteChangesを誤解していると思います。デフォルトでは、ObjectContextがクエリを実行するたびに、返されたオブジェクトのいずれかがキャッシュに既に存在する場合、それらのオブジェクトの新しく返されたコピーは無視されます。 すべてがEntityKeys

に基づいて行われることに注意してください。基本的に、クエリから返されたオブジェクトの EntityKeys がチェックされ、同じEntityKey を持つオブジェクト (同じ EntitySet 内、この場合はLectures ) が既にキャッシュに存在する場合、既存のオブジェクトはそのまま残ります。 ただし、 OverwriteChanges を有効にする

インメモリ エンティティが編集されている場合でも、データベースからの値を持つ既存のエンティティの現在の値。

ご覧のとおり、学生にとってまったく新しい講義を学生に追加しています。その EntityKey は、LoadProperty()呼び出しに従ってデータベースから取得したものとは異なるため、上書きされません。 1 つの解決策は、 LoadProperty()

の直前に学生オブジェクトからすべての講義を単純にクリアすることです。

public void CancelChanges() {
    _context.Refresh(RefreshMode.StoreWins, this);
    this.Lectures.Clear();
    _context.LoadProperty(this, (o) => o.Lectures, MergeOption.OverwriteChanges);
}
于 2010-10-01T20:02:34.087 に答える