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);
内容
内容只有自己的配置。
内容可以包含很多文字,由于某些原因,这些东西没有直接保存在Foo
table/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。
我会接受允许数据库具有我在代码库中看不到的关系的答案,但我更希望 Content
对 Foo
[=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; }
}
我正在使用 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
table/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。
我会接受允许数据库具有我在代码库中看不到的关系的答案,但我更希望 Content
对 Foo
[=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; }
}