EF删除多对多关系



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

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存在):

用户角色用户ID角色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)开始一直在努力让它发挥作用。

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

在调用Remove:之前,可以先将role附加到上下文,使第二个异常消失

_dataContext.Roles.Attach(role);
_dataContext.Roles.Remove(role);
_dataContext.SaveChanges();

但是,您很可能也会得到此代码的第一个异常,因为真正的问题是,您显然没有在数据库中分别为从UserRoles表到Users表和Roles表的两个关系启用级联删除。

您可以在SQLServerManagementStudio中将这两种关系的删除规则设置为"级联",例如此处所示。在此之后,删除角色还应删除UserRoles链接表中的条目。

编辑

加载相关用户时,您也可以在不启用级联删除的情况下成功删除角色:

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();

不同之处在于,当相关用户与角色一起附加到上下文时,EF将为UserRoles链接表中的每一行发送一个单独的DELETE语句,然后为角色发送一个DELETE语句,这样它就可以在不违反FK约束的情况下工作。

相关内容

  • 没有找到相关文章

最新更新