实体框架 - 如何从联结表中删除数据

时间:2015-08-06 18:00:45

标签: c# .net entity-framework

我的问题是 - 我有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;添加对象,因为它与另一个表相关。

4 个答案:

答案 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);