首页 > 解决方案 > EF Core 2 - 只有 1 个导航属性/关系知识的关系?

问题描述

我将 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);

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

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

如您所见,我试图确保Content没有外键/导航属性到Foo. 这是因为这些属性不是其中的一部分,Content并且因为将来更多的类/表可以包含保存在表中的IntroTextContent之类的东西,我不想Content被可为空的外键/导航属性填充。

EF Core 可以做到这一点吗?

我现在得到的错误:

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


我会接受一个答案,该答案允许数据库具有我在我的代码库中看不到的关系,但我希望它Content不知道任何关于Foo

非常感谢您的帮助!

标签: c#databaseentity-frameworkentity-framework-coreef-fluent-api

解决方案


If you have an IntroTextId exposed in your Foo entity, then you need to associate it as the FK in the One-to-One relationship:

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

Normally though I don't want FK properties exposed in my entities because this causes two sources of truth for what entity is referenced. (Foo.IntroTextId vs. Foo.IntroText.IntroTextId) In this case you leverage a shadow property for the FK:

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

This is similar (and more intuitive) to using Map(MapKey) in EF 6 to map FKs without exposing properties.

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

推荐阅读