EF删除多对多的关系

时间:2013-07-09 14:10:19

标签: entity-framework many-to-many ef-database-first

想象一下这个数据库模型:

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)。

有人能指出我正确的方向吗?

1 个答案:

答案 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约束的情况下工作。