1

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

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 UserId RoleId

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

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

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

或此错误消息:

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

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

_dataContext.Entry(role).State = EntityState.Deleted;
_dataContext.SaveChanges();

这是第二条错误消息的原因:

_dataContext.Circuit.Remove(role);
_dataContext.SaveChanges();

我做了其他一些尝试,但我不记得它们了,因为我从今天早上(格林威治标准时间 +2)开始就一直在努力让它工作。

谁能指出我正确的方向?

4

1 回答 1

5

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

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

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

您可以在 SQL Server Management Studio 中将两种关系的删除规则设置为“级联”,例如此处所示。之后删除角色也应该删除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 约束的情况下工作。

于 2013-07-09T15:53:28.270 回答