EF Core 能否在需要两端的地方配置 "real" One-To-One 关系?

Can EF Core configure a "real" One-To-One relation where both ends are required?

EF Core documentation about One-To-One relations 说:"When configuring the relationship with the Fluent API, you use the HasOne and WithOne methods." 仔细观察可以看出,这配置了 One-To-ZeroOrOne 或 ZeroOrOne-To-ZeroOrOne 关系,具体取决于是否使用 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; }
}

派生上下文 class 包含:

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()) 和 [=22 后成功=],即 ParentEntity-ChildEntity 关系是 One-To-ZeroOrOne。换句话说:child的parent是必需的,parent的child是可选的。

有没有办法配置 "real" One-To-One 两端都需要的关系?

也许这不能在数据库中强制执行。但它可以由 EF Core 强制执行吗? (顺便说一句:它可以由 EF6 强制执行。)

Is there a way to configure a "real" One-To-One relation where both ends are required?

在撰写本文时(EF Core 2.1.2),答案是否定的(不幸的是)。

文档的 Required and Optional Relationships 部分说:

You can use the Fluent API to configure whether the relationship is required or optional. Ultimately this controls whether the foreign key property is required or optional.

还有一个已关闭的问题EF Core 2: One to One Required Not Being Enforced (also Navigation no longer needed?) #9152问同样的问题,部分回复是:

when a relationship is made "Required" it means that a dependent entity cannot exist without an associated principal entity. This is done my making the FK non-nullable--i.e. the FK value must reference some principal entity.

However, it says nothing about the principal entity existing without the dependent. This is always possible because there isn't really any way to restrict it when working with partially loaded graphs. (This was the same with the old stack, although there were some situations where the state manager would, almost arbitrarily, stop certain things happening.) With stronger semantics applied to aggregates that limit partially loading of graphs it may be possible to enforce such a restriction in the future, but that isn't done yet.