尝试删除具有关系的模型时关联被切断异常

Association severed exception when trying to delete a model with relationship

这是我的模型(缩写)

用户:

public partial class User
{
    public int Id { get; set; }
    public virtual BusinessOwner BusinessOwner { get; set; }
    //rest of code
}

和 BusinessOwner,它有一个指向用户的外键 (User.Id = BusinessOwner.UserId) 这意味着企业主必须是用户。

企业主:

 public partial class BusinessOwner
{
    public int UserId { get; set; }
    public virtual User User { get; set; }
    //rest of code
}

在一个场景中,我必须删除一个用户,所以我得到了用户并包含了这样的关系:

 public User GetByIdEager(int id)
    {
        return _context.User.Where(u => u.Id == id && u.DeletedAt == null)
            .Include(u => u.BusinessOwner)
            .FirstOrDefault();
    }

这是我的控制器:

  public class UserController : ControllerBase
  {
      [HttpDelete("id")]
      public ActionResult Delete(int id)
      {
          User user = GetByIdEager(id);
          _context.User.Remove(user);
          _context.SaveChanges();
          return Ok();
      }
  }

调用 _context.User.Remove(user);

时出现以下异常

The association between entity types Users and BusinessOwners has been severed but the relationship is either marked as 'Required' or is implicitly required because the foreign key is not nullable. If the dependent/child entity should be deleted when a required relationship is severed, then setup the relationship to use cascade deletes

即使我在检索用户时包括了 BusinessOwner。有人能告诉我为什么会这样吗?我该如何解决?

好的,我想我知道出了什么问题,所以我发布它以防其他人也遇到这个问题。

docs ,事实证明存在多种类型的关系:Cascade、ClientSetNull、SetNull 和 Restrict。这些关系中的每一个都有删除行为。

At a high level:

  • If you have entities that cannot exist without a parent, and you want EF to take care for deleting the children automatically, then use Cascade.
  • Entities that cannot exist without a parent usually make use of required relationships, for which Cascade is the default.
  • If you have entities that may or may not have a parent, and you want EF to take care of nulling out the foreign key for you, then use ClientSetNull
  • Entities that can exist without a parent usually make use of optional relationships, for which ClientSetNull is the default.
  • If you want the database to also try to propagate null values to child foreign keys even when the child entity is not loaded, then use SetNull. However, note that the database must support this, and
    configuring the database like this can result in other restrictions,
    which in practice often makes this option impractical. This is why
    SetNull is not the default.
  • If you don't want EF Core to ever delete an entity automatically or null out the foreign key automatically, then use Restrict. Note that
    this requires that your code keep child entities and their foreign
    key values in sync manually otherwise constraint exceptions will be
    thrown.

然后我转到我的 DBContext,发现关系自动设置为 ClientSetNull,这就是我遇到异常的原因:BusinessOwner 中的 UserId 字段设置为 NULL,并且 table 不允许该字段中的空值。 解决方案是将删除行为设置为 Cascade 而不是 ClientSetNull。像这样 : 在我的 DbContext 中:

entity.HasOne(d => d.User)
                    .WithOne(p => p.BusinessOwner)
                    .HasForeignKey<BusinessOwner>(d => d.UserId)
                    .OnDelete(DeleteBehavior.Cascade)
                    .HasConstraintName("FK__business___user___7E37BEF6");

现在每当我删除用户时,企业主也会被删除。