子导航属性不更新 [英] Child navigation properties not updating

查看:54
本文介绍了子导航属性不更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个让我疯狂的问题。我一直在尝试正确更新包含多对多关系的实体模型。实体是Account< - >角色。以下是我更新所述导航属性的方法:



I got a problem which is driving me nuts. I have been trying to properly update an entity model which contains a many-to-many relationship. The entities are Account <--> Role. Here is how I update said navigation properties:

//EDIT

if (ModelState.IsValid)
{
   viewModel.Account.Roles.Clear();
   List<Roles> roles = viewModel.Account.Roles.ToList();
   foreach (Roles role in viewModel.RolesList)
   {
      Roles selectedRole = db.RolesSet.Find(role.Id);

      //Check if roles have changed
      if (role.IsSelected && !viewModel.Account.Roles.Contains(role))
         roles.Add(selectedRole);
      else if (!role.IsSelected && viewModel.Account.Roles.Contains(role))
         roles.Remove(selectedRole);
   }
   viewModel.Account.Roles = roles;


   db.Entry(viewModel.Account).State = System.Data.Entity.EntityState.Modified;
   db.SaveChanges();
   return RedirectToAction("Index");
}





之前我已经让它工作了,但是在另一部分失败了,因为我正在使用DbSet< T> ;。Where()方法无处不在,我为一个控制器维护了多个上下文,实质上减慢了我不必要的整个网站速度,并给了我多个Attach / Detach错误。所以我决定只使用EF的脚手架模板,我现在正在努力适应我的需求。令我感到困惑的是当我使用以下创建逻辑时:





I have gotten it to work before, but that failed on another part because I was using the DbSet<T>.Where() method everywhere and I maintained multiple contexts for one controller, essentially slowing down my whole website unnecessarily and giving me multiple Attach/Detach errors. So I decided to just use EF's scaffolding templates which I am trying to adapt to my needs now. What baffles me is when I use following Create logic:

//CREATE

if (ModelState.IsValid)
{
   foreach (Roles role in viewModel.RolesList)
   {
      if (role.IsSelected)
      {
         Roles selectedRole = db.RolesSet.Find(role.Id);
         viewModel.Account.Roles.Add(selectedRole);
      }
   }

   db.AccountsSet.Add(viewModel.Account);
   db.SaveChanges();
   return RedirectToAction("Index");
}





这样做有效。那么为什么在编辑操作中更新我的角色列表不起作用?



这是我的ViewModel类:





This works. So why does updating my Roles list in Edit action not work?

This is my ViewModel class:

public class AccountsViewModel
{
   public Accounts Account { get; set; }

   public List<Roles> RolesList { get; set; }
   //TODO Replace this with EmployeeList
   public List<Accounts> AccountsList { get; set; }

   public List<Companies> CompaniesList { get; set; }
}

推荐答案

您无需自己创建关联。这是一个简单的关联,EF知道如何处理自己。关联的表格将由EF在数据库中创建而不需要您知道。



出现问题的是您没有加载您正在修改的项目数据库进入上下文对象跟踪器。你正在做的是尝试将页面返回的viewModel视为跟踪器中的一个对象而不是它的开头。你真的不应该尝试。你已经发现了原因。


首先使用viewModel中的ID从数据库加载对象,然后你可以使用viewModel中的数据对该对象进行更改,设置Modified状态并将对象保存回数据库。

You don't need to create the association yourself. This is a simple association that EF knows how to handle itself. The associated table will be created in the database by EF without you knowing it.

What's going wrong is that you're not loading the item you're modifying from the database into the context object tracker. What you're doing is trying to treat the viewModel returned by the page as an object in the tracker without it being there to begin with. You really shouldn't try that. You've discovered why.

Load the object from the database using the ID in the viewModel first, then you can make changes to that object using the data in the viewModel, set the Modified state and save the object back to the database.
var accountToUpdate = db.Accounts
    .Where(a => a.AccountId == viewmodel.AccountId)
    .Include("Roles")
    .FirstOrDefault();

if (accountToUpdate != null)
{
    ... code to update loaded account with viewModel data ...

    db.Entity(accountToUpdate).State = EntityState.Modified;
    db.SaveChanges();
}
else
{
    ... The account specified by the viewModel doesn't exist in the database ...
}


对于遇到这种情况的每个人都好,我强烈建议您自己编码/建模关联表,以便您可以手动插入记录。起初我太懒了,但现在,CRUD角色和账户要容易得多。我现在有3个C#实体类而不是两个,即Accounts和Roles类,另外还有AccountsRoles。
Ok for everybody that comes across this, I strongly advise you to code/model the association table yourself so you can insert the records manually. I was too lazy at first but now, it is much easier to CRUD Roles and Accounts. I now have 3 C# entity classes instead of two, the Accounts and Roles classes and additionally now AccountsRoles.


这篇关于子导航属性不更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆