C# 尝试删除具有关系的模型时,关联已断开异常
这是我的模型(缩写) 用户: 和BusinessOwner,它具有用户的外键(User.Id=BusinessOwner.UserId) 这意味着企业所有者必须是用户 企业主:C# 尝试删除具有关系的模型时,关联已断开异常,c#,.net-core,entity-framework-core,entity-relationship,ef-core-3.1,C#,.net Core,Entity Framework Core,Entity Relationship,Ef Core 3.1,这是我的模型(缩写) 用户: 和BusinessOwner,它具有用户的外键(User.Id=BusinessOwner.UserId) 这意味着企业所有者必须是用户 企业主: public partial class BusinessOwner { public int UserId { get; set; } public virtual User User { get; set; } //rest of code } 在一个场景中,我必须删除一个用户,因此我得到
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();
}
}
当调用\u context.User.Remove(User)时,我得到以下异常代码>
实体类型用户和业务所有者之间的关联已被删除
已断开,但关系标记为“必需”或
隐式必需,因为外键不可为null。如果
当需要关系时,应删除从属/子实体
断开,然后设置关系以使用级联删除
即使我在检索用户时包含了BusinessOwner。有人能告诉我为什么会这样吗?我该如何修复它呢?好的,我想我知道出了什么问题,所以我会发布它,以防其他人也有这个问题
在
事实证明,有多种类型的关系:Cascade、ClientSetNull、SetNull和Restrict。这些关系中的每一个都有删除行为
在高级别:
- 如果您有没有父项就无法存在的实体,并且希望EF负责自动删除子项,则
使用级联
- 没有父对象就无法存在的实体通常使用所需的关系,而级联是默认关系
- 如果您的实体可能有父项,也可能没有父项,并且希望EF为您处理将外键置零的问题,那么
使用ClientSetNull
- 可以在没有父对象的情况下存在的实体通常使用可选关系,ClientSetNull是默认关系
- 如果希望数据库在未加载子实体时也尝试将空值传播到子外键,则使用
SetNull。但是,请注意,数据库必须支持此操作,并且
这样配置数据库可能会导致其他限制,
这在实践中往往使这一选择不切实际。这就是为什么
SetNull不是默认值
- 如果您不希望EF Core自动删除实体或自动清空外键,请使用Restrict。请注意
这要求代码保留子实体及其外部实体
手动同步键值,否则将出现约束异常
扔
然后我转到我的DBContext,发现关系被自动设置为ClientSetNull
,这就是我得到异常的原因:BusinessOwner中的UserId字段被设置为NULL,表不允许该字段为NULL。
解决方案是将删除行为设置为Cascade
,而不是ClientSetNull
。这样地:
在我的背景下:
entity.HasOne(d => d.User)
.WithOne(p => p.BusinessOwner)
.HasForeignKey<BusinessOwner>(d => d.UserId)
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("FK__business___user___7E37BEF6");
entity.HasOne(d=>d.User)
.WithOne(p=>p.BusinessOwner)
.HasForeignKey(d=>d.UserId)
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName(“FK_uuuu业务_uuuu用户_uuuuu7e37bef6”);
现在,每当我删除一个用户时,业务所有者就会被删除。欢迎使用Stack Overflow。请学习如何使用堆栈溢出,并阅读如何提高问题的质量。然后你的问题包括你的源代码,它可以被其他人编译和测试。好的,谢谢你指出这一点@你为这两个表设置了映射吗?不,我想我不需要任何映射。当我调试并单击User.BusinessOwner时,我看到它已成功加载。为什么我需要映射@奥斯曼拉希米
entity.HasOne(d => d.User)
.WithOne(p => p.BusinessOwner)
.HasForeignKey<BusinessOwner>(d => d.UserId)
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("FK__business___user___7E37BEF6");