实体框架-如何从连接表中删除数据
本文关键字:删除 数据 连接 框架 实体 | 更新日期: 2023-09-27 18:06:55
我的问题是以下-我有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(如果存在的话)。我不知道如何从这个结表中删除记录,你能帮我吗?我知道,当我从一个表中删除对象时,与该对象相关的所有数据都从连接表中删除,但我不想删除->添加对象,因为它与另一个表相关。
这是另一种解决方案,在用新列表替换整个角色之前,您首先必须加载用户的相关角色,如下所示:
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
中声明)。
你必须从用户中删除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();
首先,您需要在加载用户时包含角色:
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将知道如何更新DB。
p。你可以使用延迟加载选项,如果集合很大,你不想加载所有链接的元素。
问题是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);