首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法使用.Attach()进行更新

无法使用.Attach()进行更新
EN

Stack Overflow用户
提问于 2016-12-17 04:35:49
回答 1查看 77关注 0票数 1

我正在尝试更新我的UserRoles表,但它不会更新。我正在尝试更新两件事: 1.电子邮件2.用户角色。因为更新需要在两个表中进行,所以我使用了两个单独的命令。当我单独对电子邮件(用户)运行更新时,它可以工作,但如果我更新角色(AspUserRoles),它什么也不做。当我运行这两个程序时,它也不能工作,因为UserRoles.Attach(userRole)阻止它更新。我也没有得到任何错误。

我检查了ApplicationRole.Id和ApplicationUser.Id是否有值,它确实返回了我想要的值。

这是我的UserController.cs:

代码语言:javascript
复制
public async Task<IActionResult> Edit(UserViewModel model, Guid id)
{
    var alert = new Alert();

    try 
    {
        if(!ModelState.IsValid)
        {
            alert.Message = alert.ExceptionMessage = ApplicationDbContextMessage.INVALID;
            throw new Exception();
        }    


        var originalModel = ApplicationDbContext.Users.FirstOrDefault(u => u.Id == id);     
        var userRole = ApplicationDbContext.UserRoles.FirstOrDefault(i => i.UserId == id);  


        if(originalModel == null) 
        {
            alert.Message = alert.ExceptionMessage = ApplicationDbContextMessage.NOTEXISTS;
            throw new Exception();

        }


        originalModel.Email = model.ApplicationUser.Email;

        userRole.RoleId = model.ApplicationRole.Id;


        ApplicationDbContext.Users.Attach(originalModel);  
        ApplicationDbContext.UserRoles.Attach(userRole);


        ApplicationDbContext.Entry(originalModel).State = EntityState.Modified;


        if (await ApplicationDbContext.SaveChangesAsync() == 0)
        {
            alert.Message = alert.ExceptionMessage = ApplicationDbContextMessage.EDITNOK;
            throw new Exception();
        } 

        alert.Message = ApplicationDbContextMessage.EDITOK;
        return RedirectToAction("Index");
    }
    catch(Exception ex)
    {
        alert.Type = AlertType.Error;
        alert.ExceptionMessage = ex.Message;

        model = await ViewModel(model.ApplicationUser);

        ModelState.AddModelError(string.Empty, alert.ExceptionMessage);
    }
    return View(model);
}
EN

回答 1

Stack Overflow用户

发布于 2016-12-17 05:06:39

在这段代码中修改数据的方式是,不需要在Context上调用AttachAdd来让它知道实体的更改,这将自动发生。

从您将一个实体从DbContextDbSet中拉出的那一刻起,它就被该DbContext跟踪(附加)了。当您在DbContext上调用SaveChanges时,它将扫描它正在跟踪的任何实体,将当前值与旧值进行比较,以发现更改。然后,这些更改被发送到数据库。

从字面上看,你应该能够从你最初发布的内容中删除3行代码,并让它正常工作。

代码语言:javascript
复制
...
originalModel.Email = model.ApplicationUser.Email;
userRole.RoleId = model.ApplicationRole.Id;

ApplicationDbContext.Users.Attach(originalModel);  // <--- Delete this line
ApplicationDbContext.UserRoles.Attach(userRole);  // <--- Delete this line
ApplicationDbContext.Entry(originalModel).State = EntityState.Modified;  // <--- Delete this line

if (await ApplicationDbContext.SaveChangesAsync() == 0)
...

还有一些我注意到的东西。看起来您可能正在为整个应用程序使用单个DbContext实例。这通常被认为是Entity Framework中的"Anti-Patern“。您应该为您执行的每个“逻辑”操作创建一个新的DbContext实例(使用using)。该实例应该仅在该操作的生命周期内处于活动状态。

在MVC中,这通常是每个ActionMethod一个DbContext实例。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41192076

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档