想象一下这个数据库模型:
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string Firstname { get; set; }
public ICollection<Role> Roles { get; set; }
}
public class Role
{
public int Id { get; set; }
public string RoleType { get; set; }
public ICollection<User> Users { get; set; }
}
有一个看起来像这样的中间表(不作为POCO出现):
的UserRole 用户身份 角色ID
然后我决定删除一个角色,这意味着该角色在中间表中的所有关系也应该被删除。
无论我尝试什么,我都会收到以下错误消息:
DELETE语句与REFERENCE约束“FK_UserRole_Role”冲突。冲突发生在数据库“dbname”,表“dbo.UserRole”,列“RoleId”。
或者此错误消息:
无法删除该对象,因为在ObjectStateManager中找不到该对象。
第一条错误消息来自此尝试:
_dataContext.Entry(role).State = EntityState.Deleted;
_dataContext.SaveChanges();
这个负责第二条错误消息:
_dataContext.Circuit.Remove(role);
_dataContext.SaveChanges();
我做了一些其他的尝试,但我不记得了,因为我一直试图从今天早上开始工作(GMT +2)。
有人能指出我正确的方向吗?
答案 0 :(得分:5)
您可以在致电role
之前先将Remove
附加到上下文,以使第二个例外消失:
_dataContext.Roles.Attach(role);
_dataContext.Roles.Remove(role);
_dataContext.SaveChanges();
但是你很可能也会得到这个代码的第一个例外,因为真正的问题是你显然没有在数据库中为从UserRoles
表到{{1}的两个关系启用级联删除分别表和Users
表。
您可以在SQL Server Management Studio like show here for example中将两个关系的删除规则设置为“Cascade”。之后,删除角色还应删除Roles
链接表中的条目。
修改强>
加载相关用户时,您也可以成功删除角色,而无需启用级联删除:
UserRoles
不同之处在于,当相关用户与角色一起附加到上下文时,EF将为var role = _dataContext.Roles.Include(r => r.Users)
.Single(r => r.Id == someRoleId);
_dataContext.Roles.Remove(role);
// _dataContext.Entry(role).State = EntityState.Deleted; will work as well
_dataContext.SaveChanges();
链接表中的每一行发送单独的DELETE语句,然后为该角色发送DELETE语句,以便它在不违反FK约束的情况下工作。