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

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

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

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

在 context.SaveChanges() 行中,我抛出了一个 DbUpdateConcurrencyException 异常。它说,“存储更新、插入或删除语句影响了意外数量的行 (0)。自加载实体以来,实体可能已被修改或删除。刷新 ObjectStateManager 条目。

我不知道为什么。

这是我所做的:

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 的实例在 Controller 操作中,这意味着它处于类级别。这意味着 context与该 Controller 处理的所有其他 Web 请求共享。这部分错误信息Entities may have been modified or deleted since entities were loaded似乎证实了这个假设。

相反,创建一个 context 的实例在您的 Controller 操作中。

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

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

更新

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

关于c# - 保存对用户帐户的更改导致 DbUpdateConcurrencyException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31545657/

相关文章:

visual-studio-code - 如何在 VS Code 中使用 `Scaffold-DbContext` 命令

entity-framework - 使用 EF Code First Fluent API 时如何将数据库列设置为 "Sparse"?

javascript - ASP.NET MVC 中的拖放区错误消息

c# - MVC 图表仅显示文本流

asp.net-mvc - 带有继承的 MVC 5 脚手架使用了错误的实体集

c# - 将PHP解密AES-256-CBC移植到C#

c# - 如何使用模型绑定(bind)在 C# MVC 4 中创建而不是编辑具有对象列表的对象?

c# - 如何将对象列表转换为 csv?

c# - 单元测试 - 更新模型

c# - 什么可以替代 MSTest 中的 [TearDown] 和 [SetUp]?