我正在将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
被可空的外键/导航属性填充。
我现在遇到的错误:
对于'Foo.IntroText'和'Content'之间的一对一关系,无法确定子/从属方面。要标识关系的子级/从属端,请配置外键属性。如果这些导航不应该是相同关系的一部分,请在不指定反向关系的情况下进行配置。有关更多详细信息,请参见http://go.microsoft.com/fwlink/?LinkId=724062。
我会接受一个答案,该答案允许数据库具有我在代码库中看不到的关系,但我更希望Content
对Foo
一无所知
非常感谢您的帮助!
答案 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; }
}