保存对用户帐户的更改导致 DbUpdateConcurrencyException

Saving changes to user account result in DbUpdateConcurrencyException

我有一个表单,用户可以在其中编辑他们的用户帐户信息,然后保存新的更改。

当我将修改后的更改保存到数据库时,我遇到了这个问题。

在行 context.SaveChanges() 中,我抛出了 DbUpdateConcurrencyException 异常。它说,"Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries."

我不知道为什么。

这是我所做的:

public ActionResult EditUserAccount()
{
    UserAccountViewModel editUserAccountViewModel = new UserAccountViewModel();
    editUserAccountViewModel.UserName = UserSession.GetValue(StateNameEnum.UserName, StateNameEnum.UserName.ToString()) as string;
    int UserId = WebSecurity.GetUserId(editUserAccountViewModel.UserName);
    var userInfo = context.db_user.First(x => x.UserId == UserId);

    editUserAccountViewModel.Title = userInfo.Title;
    editUserAccountViewModel.FirstName = userInfo.FirstName;
    editUserAccountViewModel.LastName = userInfo.LastName;
    editUserAccountViewModel.PhoneNumber = userInfo.PhoneNumber;
    editUserAccountViewModel.AltPhoneNumber = userInfo.AltPhoneNumber;
    editUserAccountViewModel.EmailAddress = userInfo.EmailAddress;
    editUserAccountViewModel.UserAccountState = UserAccountViewModel.AccountState.EDIT;
    return (PartialView("~/Views/Account/UserAccount.cshtml", editUserAccountViewModel));

}

[HttpPost]
public ActionResult EditUserAccount_Save(UserAccountViewModel editUserAccountViewModel)
{
    try
    {
        if (ModelState.IsValid)
        {
            editUserAccountViewModel.UserName = UserSession.GetValue(StateNameEnum.UserName, StateNameEnum.UserName.ToString()) as string;

            db_user user = new db_user();
            user.Title = editUserAccountViewModel.Title;
            user.FirstName = editUserAccountViewModel.FirstName;
            user.LastName = editUserAccountViewModel.LastName;
            user.PhoneNumber = editUserAccountViewModel.PhoneNumber;
            user.AltPhoneNumber = editUserAccountViewModel.AltPhoneNumber;
            user.EmailAddress = editUserAccountViewModel.EmailAddress;
            user.LanguageId = context.languages.Where(t => t.Code == editUserAccountViewModel.Language).Select(t => t.Id).SingleOrDefault();
            user.CreatedDate = DateTime.Now;
            user.UserId = WebSecurity.GetUserId(editUserAccountViewModel.UserName);

            context.Entry(user).State = EntityState.Modified;
            context.SaveChanges();

            JsonResult res = Json(new { Success = true, data = "", Message = "" });
            return res;
        }
        else
        {
            JsonResult res2 = Json(new { Success = false, data = "", Message = "" });
            return res2;
        }
    }
    return null;
}

您没有在控制器操作中创建 context 的实例,这意味着它处于 class 级别。这意味着 context 与该控制器处理的所有其他 Web 请求共享。错误消息的这一部分 Entities may have been modified or deleted since entities were loaded 似乎证实了这个假设。

相反,在您的控制器操作中创建 context 的实例。

由于您在此操作中编辑现有用户,因此您首先需要将现有用户从数据库加载到 context,而不是像现在这样实例化一个新用户。

我强烈怀疑此更改将解决您的问题。

更新

这是一个代码示例。我不知道你的上下文 class 叫什么,所以你可能需要更改那部分。我假设调用此控制器时用户必须已经存在(基于方法的名称)。我删除了 try 因为你没有捕捉到任何东西。如果抛出异常时您可以做一些有用的事情,请继续并把它放回去。

[HttpPost]
public ActionResult EditUserAccount_Save(UserAccountViewModel editUserAccountViewModel)
{
    if (ModelState.IsValid)
    {
        using (MyContext context = new MyContext())
        {
            int userId = WebSecurity.GetUserId(editUserAccountViewModel.UserName);
            db_user user = context.DbUsers.Where(u => u.Id == userId).Single();
            editUserAccountViewModel.UserName = UserSession.GetValue(StateNameEnum.UserName, StateNameEnum.UserName.ToString()) as string;

            user.Title = editUserAccountViewModel.Title;
            user.FirstName = editUserAccountViewModel.FirstName;
            user.LastName = editUserAccountViewModel.LastName;
            user.PhoneNumber = editUserAccountViewModel.PhoneNumber;
            user.AltPhoneNumber = editUserAccountViewModel.AltPhoneNumber;
            user.EmailAddress = editUserAccountViewModel.EmailAddress;
            user.LanguageId = context.languages.Where(t => t.Code == editUserAccountViewModel.Language).Select(t => t.Id).SingleOrDefault();
            user.CreatedDate = DateTime.Now;

            context.SaveChanges();

            JsonResult res = Json(new { Success = true, data = "", Message = "" });
            return res;
        }
    }
    else
    {
        JsonResult res2 = Json(new { Success = false, data = "", Message = "" });
        return res2;
    }
}