0

各タスクには、割り当てられている目標への参照があります。タスクを削除しようとすると、目標がエラーになります

「ストアの更新、挿入、または削除ステートメントが予期しない行数(0)に影響しました。エンティティがロードされてから、エンティティが変更または削除された可能性があります。ObjectStateManagerエントリを更新してください。」行_goalRepository.Delete(goalId);

私は何が間違っているのですか?

 [HttpPost]
    public void DeleteGoal(int goalId, bool deleteTasks)
    {
        try
        {
            if (deleteTasks)
            {
                Goal goalWithTasks = _goalRepository.GetWithTasks(goalId);

                foreach (var task in goalWithTasks.Tasks)
                {
                    _taskRepository.Delete(task.Id);
                }
                goalWithTasks.Tasks = null;
                _goalRepository.Update(goalWithTasks);

            }

            _goalRepository.Delete(goalId);

        }
        catch (Exception ex)
        {
            Exception deleteException = ex;
        }
    }
4

3 に答える 3

1

おそらく問題は、ページビュー全体でコンテキストを保持して再利用しようとしているためです。新しいコンテキストを作成し、作業を行い、コンテキストをアトミックに破棄する必要があります。これは、作業単位パターンと呼ばれます。

これの主な理由は、コンテキストが表示したデータベース行に関するいくつかの状態情報を維持しているためです。その状態情報が古くなったり古くなったりすると、このような例外が発生します。

作業単位パターンを使用する理由は他にもたくさんあります。教育演習として、Web検索を行い、少し読んでみることをお勧めします。

于 2012-06-08T17:37:24.110 に答える
1

ただし、これはデータアクセスとは関係がない場合があります。リストを反復処理しているときにリストからアイテムを削除しているため、通常のリストを使用している場合は問題が発生します。EFの内部についてあまり知らなくても、リポジトリへのdelete呼び出しは、繰り返しているのと同じリストを変更していると思います。

1回のパスでリストを繰り返し、削除するタスクIDを別のリストに記録してみてください。次に、反復が終了したら、タスクリストでdeleteを呼び出します。例えば:

var tasksToDelete = new List<int>();
foreach (var task in goalWithTasks.Tasks)
{
    tasksToDelete.Add(task.Id);
}

foreach (var id in tasksToDelete)
{
    _taskRepository.Delete(id);
}

これは問題の原因ではないかもしれませんが、反復しているコレクションを決して変更しないことをお勧めします。

于 2012-06-08T18:15:15.243 に答える
0

私は職場でこの問題に遭遇しました(私はインターンです)。他のデータテーブルで参照されている機器を削除しようとすると、このエラーが発生していました。

機器を削除する前にすべての参照を削除していましたが、独自のデータベースコンテキストを持つ別のモデルで参照の削除が行われていたため、参照の削除はモデルのコンテキスト内に保存されていました。しかし、機器モデルのコンテキストは、別のモデルのコンテキストで発生した変更を認識しません。そのため、機器を削除してから変更を保存しようとすると(db.SaveChanges()など)、エラーが発生します(機器コンテキストは、他の表にその機器への参照があるとまだ考えていました)。

これに対する私の解決策は、機器を削除する前にコンテキストを再割り当てすることでした。

db = new DatabaseContext();

これで、新しく割り当てられたコンテキストにデータベースの最新のスナップショットがあり、行われたすべての変更が認識されます。削除は問題なく行われます。

私の経験がお役に立てば幸いです。

于 2015-05-22T19:50:23.530 に答える