EF删除多对多的关系

Yus*_*tme 1 many-to-many entity-framework 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; }
}
Run Code Online (Sandbox Code Playgroud)

有一个看起来像这样的中间表(不作为POCO出现):

UserRole UserId RoleId

然后我决定删除一个角色,这意味着也应删除该角色在中间表中的所有关系.

无论我尝试什么,我都会收到以下错误消息:

DELETE语句与REFERENCE约束"FK_UserRole_Role"冲突.冲突发生在数据库"dbname",表"dbo.UserRole",列"RoleId"中.

或者此错误消息:

无法删除该对象,因为在ObjectStateManager中找不到该对象.

第一条错误消息来自此尝试:

_dataContext.Entry(role).State = EntityState.Deleted;
_dataContext.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

这个负责第二条错误消息:

_dataContext.Circuit.Remove(role);
_dataContext.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

我做了一些其他的尝试,但我不记得了,因为我一直试图从今天早上开始工作(GMT +2).

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

Sla*_*uma 5

您可以通过role在调用之前首先附加到上下文来使第二个异常消失Remove:

_dataContext.Roles.Attach(role);
_dataContext.Roles.Remove(role);
_dataContext.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

但是,您很可能也会获得此代码的第一个例外,因为真正的问题是您显然没有在数据库中为UserRoles表中的Users表和Roles表以及表分别启用级联删除.

您可以在SQL Server Management Studio中将两个关系的删除规则设置为"Cascade",例如在此处显示.删除角色后,还应删除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();
Run Code Online (Sandbox Code Playgroud)

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