EF Core documentation about One-To-One relations说:“在配置Fluent API的关系时,您使用HasOne
和WithOne
方法。” 仔细观察表明,这将根据是否使用IsRequired
来配置“一对零”或“零或一对零”关系。示例:
public class ParentEntity
{
public Int64 Id { get; set; }
public ChildEntity Child { get; set; }
}
public class ChildEntity
{
public Int64 Id { get; set; }
public ParentEntity Parent { get; set; }
}
派生的上下文类包含:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ParentEntity>().HasOne(p => p.Child).WithOne(d => d.Parent)
.HasForeignKey<ChildEntity>("ParentFk").IsRequired();
}
在这种配置下,context.SaveChanges
在context.Add(new ChildEntity())
之后失败(由于SqlException: Cannot insert the value NULL into column 'ParentFk' ...
而在IsRequired
下失败),但在context.Add(new ParentEntity())
和context.Add(new ChildEntity() { Parent = new ParentEntity() })
之后成功,即ParentEntity-ChildEntity
关系是一对零或一个。换句话说:孩子的父母是必需的,父母的孩子是可选的。
是否有一种方法可以在需要两端的情况下配置“真实的”一对一关系?
也许这不能在数据库中强制执行。但是它可以由EF Core强制执行吗? (顺便说一句:它可以由EF6强制执行。)
答案 0 :(得分:3)
是否有一种方法可以在需要两端的情况下配置“真实的”一对一关系?
在撰写本文时(EF Core 2.1.2),(不幸的)答案是肯定的。
文档的Required and Optional Relationships部分说:
您可以使用Fluent API来配置关系是必需的还是可选的。最终,这将控制外键属性是必需的还是可选的。
还有一个封闭的问题EF Core 2: One to One Required Not Being Enforced (also Navigation no longer needed?) #9152提出了同样的问题,部分回应是:
将关系设为“必需”时,这意味着从属实体如果没有关联的主体实体就不能存在。这是我使FK不可为空-即FK值必须引用某些主体。
但是,它没有说明没有依赖者存在的主体实体。这始终是可能的,因为在处理部分加载的图形时,实际上没有任何方法可以限制它。 (这与旧堆栈相同,尽管在某些情况下状态管理器几乎会任意停止某些事情的发生。)通过将强语义应用到限制图的部分加载的聚合,可能可以强制执行这种操作。限制,但尚未完成。