使用子项更新数据库条目

本文关键字:数据库 更新 | 更新日期: 2023-09-27 18:35:26

>我有以下模型

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

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

存储更新、插入或删除语句受意外影响 行数 (0)。此后,实体可能已被修改或删除 实体已加载。刷新对象状态管理器条目。

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

我的控制器

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);
}

使用子项更新数据库条目

试试这个

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

任何冲突的更改将导致乐观并发异常

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

感谢用户@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

在您看来,请确保添加此内容

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

我得到了异常 原因是我的实体有一个映射为

    HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

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