EF Core 2 - 只有 1 个导航 property/relationship 知识的关系?

EF Core 2 - Relationship with only 1 navigation property/relationship knowledge?

我正在使用 ASP.NET Core 2.2 与 EF Core 2.2 和 SQL 服务器。

我目前正在开发一项功能,其中包含以下 类:

TABLE Foo
-------------------------------------------------------------
Column                       Type          Remark
--------------------------------------------------------------
Id                           GUID          PK
IntroId                      GUID?         Nullable FK
IntroText                    Content       Navigation Property
--------------------------------------------------------------

TABLE Content
--------------------------------------------------------------
Column                       Type          Remark
--------------------------------------------------------------
Id                           GUID          PK
Text                         string
--------------------------------------------------------------

这是与我的问题相关的流畅 API 配置:

builder.HasOne(b => b.IntroText)
    .WithOne()
    .IsRequired(false);

内容
内容只有自己的配置。

内容可以包含很多文字,由于某些原因,这些东西没有直接保存在Footable/class中。

如您所见,我正在努力确保 Content 没有外国 key/navigation 属性 到 Foo。这是因为这些属性不是 Content 的一部分,并且因为将来会有更多 classes/tables 可以拥有像 IntroText 这样的东西,这些东西保存在 Content table 并且我不希望 Content 被可空的外部 keys/navigation 属性填充。

EF Core 可以吗?

我现在得到的错误:

'Foo.IntroText'和'Content'之间的一对一关系无法确定child/dependent端。要识别关系的 child/dependent 端,请配置外键 属性。如果这些导航不应属于同一关系的一部分,请在不指定反向的情况下配置它们。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=724062


我会接受允许数据库具有我在代码库中看不到的关系的答案,但我更希望 ContentFoo[=22 一无所知=]

非常感谢您的帮助!

如果您在 Foo 实体中公开了一个 IntroTextId,那么您需要将其关联为 One-to-One 关系中的外键:

builder.HasOne(b => b.IntroText)
    .WithOne()
    .HasForeignKey(b => b.IntroTextId)
    .IsRequired(false);

通常我不希望 FK 属性在我的实体中公开,因为这会导致引用实体的两个真实来源。 (Foo.IntroTextId 与 Foo.IntroText.IntroTextId)在这种情况下,您为 FK 使用阴影 属性:

builder.HasOne(b => b.IntroText)
    .WithOne()
    .HasForeignKey("IntroTextId")
    .IsRequired(false);

这类似于(并且更直观)在 EF 6 中使用 Map(MapKey) 在不公开属性的情况下映射 FK。

.Map(x => x.MapKey("IntroTextId"));

另一种可能的解决方案是将两个键作为一个键处理。由于这是一对一的关系,因此 Tables Foo 和 Content 的键值应该相同。您可以使用 Foo class 中的属性通过以下方式实现它(因为未将 FluentAPI 指定为要求):

class Foo
{
   [Key, ForeignKey(nameof(Foo.IntroText))]
   public Guid Id { get; set; }

   public Content IntroText { get; set; }
}


class Content
{
   public Guid Id { get; set; }

   public string Text { get; set; }
}