我的问题是 - 我有2个表(用户,角色),具有多对多关系。当我想为用户添加新角色时,一切正常,但我无法从用户中删除角色。
List<Role> roles = new List<Role>();
roles.Add(role1); roles.Add(role3);
User user = db.users.Find(1);
user.roles = roles;
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
如上所述,此代码插入新角色(1,3),但不删除角色2(如果存在)。 我不知道如何从这个联结表中删除记录,你能帮帮我吗? 我知道,当我从一个表中删除对象时,与该对象相关的所有数据都将从联结表中删除,但我不想删除 - &gt;添加对象,因为它与另一个表相关。
答案 0 :(得分:2)
这是另一种解决方案,首先必须在用新列表替换整个角色之前加载用户的相关角色,如下所示:
User user = db.users.Include<User, ICollection<Role>>(u=>u.roles)
.FirstOrDefault(u=>u.ID == 1);
if(user != null){
user.roles = roles;
db.SaveChanges();
}
我认为您的roles
导航属性的类型为ICollection<Role>
且用户的关键属性为ID
,您可以阅读有关使用Include
扩展方法的更多信息(在QueryableExtensions
中声明。
答案 1 :(得分:1)
您必须从用户中删除role2。
List<Role> roles = new List<Role>();
roles.Add(role1); roles.Add(role3);
User user = db.users.Find(1);
user.roles.Remove(role2);
user.roles = roles;
db.SaveChanges();
答案 2 :(得分:1)
首先,您需要在加载用户时包含角色:
var user = db.users
.Include(x=>x.Roles)
.Single(x=>x.Id == 1);
然后您需要确定要删除的角色:
var roleToRemove = user.roles.Single(x => x.Id == 1);
最后删除角色并保存更改
user.Roles.Remove(roleToRemove);
db.SaveChanges();
为了让DbContext能够跟踪更改,您必须首先加载集合,然后只需修改该集合,DbContext就会知道如何更新数据库。
PS。如果集合很大并且您不想加载所有链接元素,则可以使用延迟加载选项。
答案 3 :(得分:1)
问题是EF不知道您要删除旧角色。当您使用新列表设置Roles
导航属性时,您只是告诉EF您要添加这两个新角色,但是您没有将旧角色的状态更改为Deleted
。有两种方法可以满足您的需求:
将状态更改为Deleted
:
User user = db.users.Find(1);
// change the state to Deleted.
foreach(var r in user.Roles)
db.Entry(r).State = System.Data.Entity.EntityState.Deleted;
// Add the new roles
user.Roles.AddRange(roles);
使用Remove
方法:
User user = db.users.Find(1);
// delete older roles
foreach(var r in user.Roles.ToList())
user.Roles.Remove(r);
// Add the new roles
user.Roles.AddRange(roles);