繁体   English   中英

MVC3:存储库更新和ObjectStateManager

[英]MVC3: Repository Updates and ObjectStateManager

我的存储库中有一个Update方法,用于更新项目中的文章。 最初,我只是使用这种方法来对文章进行管理员编辑。 它可以正确处理,但是我决定添加一种简单的机制来计算“阅读次数最多”的文章。 为了做到这一点,我想在每次查看文章时更新TimesRead属性。 这给我带来了麻烦,似乎无法使用ObjectStateManager.ChangeObjectState进行更新。 这是我的Update方法:

public void Update(Article article)
{
    if (article == null) return;

    db.Articles.Attach(article);
    db.ObjectStateManager.ChangeObjectState(article, EntityState.Modified);
    db.SaveChanges();
}

在我的AdminController ,以下方法正确更新:

[HttpPost]
public ActionResult Edit(AdminEditViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        Article article = Mapper.Map<AdminEditViewModel, Article>(viewModel);
        articleRepository.Update(article);

        return RedirectToAction("Index");
    }

    viewModel.Categories = new SelectList(categoryRepository.GetAll(), "CategoryID", "Name", viewModel.CategoryID);

    return View(viewModel);
}

但是,在TimesRead方案中,更新将触发以下异常:

无法附加对象,因为它已经在对象上下文中。 仅当对象处于未更改状态时才能重新附加对象。

该控制器方法中的相关代码:

var model = articleRepository.GetByID(id);

model.TimesRead++;
articleRepository.Update(model);

return View(model);

在环顾四周以了解如何解决此问题后,我遇到了这个 SO问题的答案。 因此,我通过使用建议的代码替换Update方法来实现该答案。 这在我的管理方案中也可以正常工作,但在TimesRead方案中则TimesRead 引发以下异常:

具有相同键的对象已存在于ObjectStateManager中。 ObjectStateManager无法使用相同的键跟踪多个对象。

异常的含义非常清楚,但确实让我想知道如何处理此类简单更新。 我发现我可以通过设置EntityState.Unchanged来“愚弄” EF,使其认为模型未更改,这将更新TimesRead但为管理员更新提供了一个例外,指出ObjectStateManager不保存对该对象的引用。

我也很清楚这些情况有何不同。 Edit操作将属性从ViewModel映射到新的未附加的Article对象,而ArticleController处理直接从上下文检索的对象。 这让我有一种感觉,我应该重构那些控制器方法中的一种,以便进行更新的步骤是相同的​​。 我只是不太确定该如何处理,因为这两种方法似乎都应该能够与我共存。 所以我的问题是,我该如何更改才能使两种类型的更新正常工作?

感谢您的宝贵时间,对于所发布的大量代码,我感到非常抱歉。 我只是觉得这与问题有关。

两种方法之间的主要区别是Admin Edit方法从AdminEditViewModel创建一个新的Article,然后将这个新创建的Article附加到您的数据库中。 之所以有效,是因为它是从未连接到dc的新对象。

在第二种情况下,您从存储库中获取了一条Article,对该Article进行了更新,然后尝试再次附加它,这失败了,因为它不是新创建的Article,它是从db Context返回的Article,因此它已经附加了。 您正在尝试再次附加它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM