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

c# database ef-fluent-api entity-framework entity-framework-core

Question

I am using ASP.NET Core 2.2 with EF Core 2.2 and SQL server.

I am currently working on a feature where I have the following classes:

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
--------------------------------------------------------------

This is my fluent API configuration related to my issue:

Foo

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

Content
Content only has configuration for itself.

Content can contain a lot of text and because of reasons, these things are not saved directly in the Foo table/class.

As you can see, I am trying to make sure that Content does not have a foreign key/navigation property to Foo. This is because these properties are not part of Content and because in the future more classes/tables can have stuff like IntroText's that are saved in the Content table and I dont want Content to be filled up with nullable foreign keys/navigation properties.

Is this possible with EF Core?

The error I get right now:

The child/dependent side could not be determined for the one-to-one relationship between 'Foo.IntroText' and 'Content'. To identify the child/dependent side of the relationship, configure the foreign key property. If these navigations should not be part of the same relationship configure them without specifying the inverse. See http://go.microsoft.com/fwlink/?LinkId=724062 for more details.


I would accept an answer that allows the database to have a relationship which I do not see in my codebase, but I would prefer that Content does not know anything about Foo

Thank you very much for your help!

1
2
5/16/2019 2:44:24 PM

Accepted Answer

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"));
1
5/16/2019 9:27:15 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow