2

我有以下型号

public class CourseModel
{
    [Key]
    public int courseID { get; set; }
    ...
    public virtual ICollection<CourseMeetModel> meets { get; set; }
}

当我尝试编辑其中一个条目并且输入有效时,它可以正常工作。但是,如果它无效,它会提醒用户注意错误。一旦用户修复错误并尝试保存,我就会得到以下异常。

存储更新、插入或删除语句影响了意外数量的行 (0)。自加载实体后,实体可能已被修改或删除。刷新 ObjectStateManager 条目。

我注意到如果输入未能通过我的控制器中的验证步骤,就会发生这种情况。

我的控制器

public ActionResult EditCourseConfirmed(CourseModel course)
{
        CoursesDBContext db = new CoursesDBContext();
        bool valid = validateCouse(course); //If this fails and the course model is returned back to the view I get that error
        if (valid)
        {
                try
                {
                    db.Entry(course).State = EntityState.Modified;
                    db.SaveChanges();
                    Session[d.s_Clear] = false;
                    return RedirectToAction("Index");
                }
                catch (Exception e)
                {
                    ModelState.AddModelError(string.Empty, "Unable to save the course, please try again." + e.Message);
                    return View(course);
                }

        }

        return View(course);
}
4

4 回答 4

2

试试这个

try {
   context.SaveChanges();
} 
catch (OptimisticConcurrencyException) 
{
    context.Refresh(RefreshMode.ClientWins, db.table);
    context.SaveChanges();
}

道具:https ://stackoverflow.com/a/6848729/1166147

根据您的评论添加解释。感谢您的 EF4 CTP5 提示。很高兴这解决了它,请标记为已接受。当您收到此错误时,在加载和更新之间发生了改变数据(另一个用户等)的事情,存在导致问题的触发器,或者如果使用存储过程,它达到 0 recs。没有更多信息很难知道。这是第一次更新吗?在用户遇到错误,修改,然后尝试继续而不刷新之前,是否有另一个更新运行成功?你有什么触发器吗?您的并发度是多少 - 在此用户的查询和更新之间是否有其他用户编辑和保存?阅读我给出的帖子的链接 - 有人在实体键的元数据中提到了 ReadOnlyAttribute 被替换,

(根据 MSDN 修改)默认情况下,Entity Framework 实现了一个乐观并发模型。这意味着在查询数据和更新数据之间不会对数据源中的数据进行锁定,如果另一个用户修改了数据,则可能会出现此错误。使用此属性时,实体框架会在保存更改之前检查数据库中的更改。

任何有冲突的更改都会导致 OptimisticConcurrencyException

当您定义使用存储过程对数据源进行更新的实体数据模型时,也会发生 OptimisticConcurrencyException。在这种情况下,当用于执行更新的存储过程报告零行已更新时,将引发异常。SET NOCOUNT ON 可以解决这个问题。

于 2012-05-27T21:57:44.507 回答
2

感谢用户@user1166147,它导致了 dbupdate 异常,但我仍然不知道为什么......

由于 EF4 CTP5 DbContext 没有刷新方法,我最终这样做了:

    try
    {
        db.SaveChanges();
    }
    catch (DbUpdateConcurrencyException e)
    {
        var entry = e.Entries.Single();
        entry.OriginalValues.SetValues(entry.CurrentValues);
        entry.CurrentValues.SetValues(entry.CurrentValues);
        db.SaveChanges();
    }

更多细节在这里http://blogs.msdn.com/b/adonet/archive/2011/02/03/using-dbcontext-in-ef-feature-ctp5-part-9-optimistic-concurrency-patterns.aspx

于 2012-05-27T23:08:45.333 回答
1

在您看来,请确保添加此

@Html.HiddenFor(m => m.courseID)
于 2012-05-27T22:12:22.500 回答
1

我得到了例外原因是我的实体有一个带有映射的键

    HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

当我添加了一个新实体并提供了一个 id 时,在保存时上下文会认为它是一个修改过的实体而不是一个新实体,所以我没有为键提供值并且在保存时我检查键的默认值价值,从中我知道它是新的还是修改的

于 2013-04-15T17:38:26.990 回答