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

时间:2015-07-21 17:22:11

标签: c# asp.net-mvc-4 dbcontext

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

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

在行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;
}

1 个答案:

答案 0 :(得分:3)

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

而是在控制器操作中创建context的实例。

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

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

<强>更新

这是一个代码示例。我不知道你的上下文类被调用了什么,所以你可能不得不改变那个部分。我假设调用此控制器时用户必须已存在(基于方法名称)。我删除了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;
    }
}