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

问题很可能是因为您试图在页面视图中保持并重用上下文。你应该创建一个新的上下文,做你的工作,然后原子地处理上下文。它被称为工作单元模式。

这样做的主要原因是上下文维护了一些关于它所看到的数据库行的状态信息,如果该状态信息变得陈旧或过时,那么你会得到这样的异常。

使用工作单元模式还有很多其他原因,我建议您进行网络搜索并进行一些阅读作为教育练习。

于 2012-06-08T17:37:24.110 回答
1

不过,这可能与数据访问无关。您在迭代列表时从列表中删除项目,如果您使用的是普通列表,这将导致问题。在不了解 EF 内部的情况下,我的猜测是您对存储库的删除调用正在更改您正在迭代的同一个列表。

尝试一次迭代列表,并在单独的列表中记录要删除的任务 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 回答