使用子级更新数据库条目

时间:2012-05-27 21:40:19

标签: c# asp.net asp.net-mvc asp.net-mvc-3 entity-framework

我有以下模型

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 个答案:

答案 0 :(得分: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修改)默认情况下,实体框架实现乐观并发模型。这意味着在查询数据和更新数据之间,数据源中的数据不会保留锁定,如果其他用户修改了数据,则可能会产生此错误。使用此属性时,实体框架会在保存更改之前检查数据库中的更改

任何冲突的更改导致OptimisticConcurrencyException

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

答案 1 :(得分: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

答案 2 :(得分:1)

在您的视图中,请务必添加此

@Html.HiddenFor(m => m.courseID)

答案 3 :(得分:1)

我得到了异常原因是我的实体有一个带有

映射的Key
    HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

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

相关问题