EF Core是否可以在需要两端的地方配置“真实的”一对一关系?

时间:2018-09-04 14:54:11

标签: entity-framework-core ef-fluent-api

EF Core documentation about One-To-One relations说:“在配置Fluent API的关系时,您使用HasOneWithOne方法。” 仔细观察表明,这将根据是否使用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.SaveChangescontext.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强制执行。)

1 个答案:

答案 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值必须引用某些主体。

     

但是,它没有说明没有依赖者存在的主体实体。这始终是可能的,因为在处理部分加载的图形时,实际上没有任何方法可以限制它。 (这与旧堆栈相同,尽管在某些情况下状态管理器几乎会任意停止某些事情的发生。)通过将强语义应用到限制图的部分加载的聚合,可能可以强制执行这种操作。限制,但尚未完成。