EF Core 2-仅具有1个导航属性/关系知识的关系?

时间:2019-05-16 14:44:25

标签: c# database entity-framework entity-framework-core ef-fluent-api

我正在将ASP.NET Core 2.2与EF Core 2.2和SQL Server一起使用。

我目前正在开发具有以下课程的功能:

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配置:

Foo

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

内容
内容仅具有自身的配置。

内容可能包含很多文本,并且由于某些原因,这些内容不会直接保存在Foo表/类中。

如您所见,我正在尝试确保Content没有Foo的外键/导航属性。这是因为这些属性不是Content的一部分,并且因为将来会有更多的类/表包含诸如 IntroText 之类的东西,它们会保存在Content表中,而我不希望Content被可空的外键/导航属性填充。

EF核心有可能吗?

我现在遇到的错误:

对于'Foo.IntroText'和'Content'之间的一对一关系,无法确定子/从属方面。要标识关系的子级/从属端,请配置外键属性。如果这些导航不应该是相同关系的一部分,请在不指定反向关系的情况下进行配置。有关更多详细信息,请参见http://go.microsoft.com/fwlink/?LinkId=724062


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

非常感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

如果在Foo实体中公开了IntroTextId,则需要将其作为一对一关系中的FK关联:

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

通常,尽管我不希望在实体中公开FK属性,因为这会导致引用哪个实体的两个事实来源。 (Foo.IntroTextId与Foo.IntroText.IntroTextId)在这种情况下,您可以为FK利用shadow属性:

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

这类似于(更直观)与在EF 6中使用Map(MapKey)映射FK而不公开属性。

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

答案 1 :(得分:0)

另一种可能的解决方案是将两个键作为一个进行处理。由于这是一对一的关系,表 Foo 和 Content 的键应该是相同的值。您可以通过以下方式使用 Foo 类中的属性实现它(因为 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; }
}