有关一对一关系的 EF Core 文档说:">配置与 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())
后失败(由于IsRequired
而SqlException: Cannot insert the value NULL into column 'ParentFk' ...
(,但在context.Add(new ParentEntity())
和context.Add(new ChildEntity() { Parent = new ParentEntity() })
后成功,即ParentEntity-ChildEntity
关系是 1 比 ZeroOrOne。换句话说:子项的父项是必需的,父项的子项是可选的。
有没有办法配置需要两端的"真正的"一对一关系?
也许这不能在数据库中强制执行。但是,是否可以由 EF Core 强制执行?(顺便说一句:它可以由 EF6 强制执行。
有没有办法配置需要两端的"真正的"一对一关系?
在撰写本文时(EF Core 2.1.2(,答案(不幸的是(是否定的。
文档的"必需和可选关系"部分指出:
您可以使用 Fluent API 配置关系是必需的还是可选的。最终,这控制外键属性是必需的还是可选的。
还有一个已关闭的问题 EF Core 2:一对一需要不强制执行(也不再需要导航?(#9152 问同样的问题,部分响应是:
当关系变为"必需"时,这意味着没有关联的主体实体,依赖实体就无法存在。这是我使 FK 不可为空的 - 即FK 值必须引用某个主体实体。
但是,它没有说明没有依赖者而存在的主要实体。这始终是可能的,因为在处理部分加载的图形时,实际上没有任何方法可以限制它。(这与旧堆栈相同,尽管在某些情况下,状态管理器几乎会任意阻止某些事情的发生。通过将更强的语义应用于限制部分图形加载的聚合,将来可能会强制执行这样的限制,但这还没有完成。