@@ -20,6 +20,84 @@ public class TodoItem : Identifiable<int>
2020
2121The left side of this relationship is of type ` TodoItem ` (public name: "todoItems") and the right side is of type ` Person ` (public name: "persons").
2222
23+ ### Required one-to-one relationships in Entity Framework Core
24+
25+ By default, Entity Framework Core generates an identifying foreign key for a required 1-to-1 relationship.
26+ This means no foreign key column is generated, instead the primary keys point to each other directly.
27+
28+ The next example defines that each car requires an engine, while an engine is optionally linked to a car.
29+
30+ ``` c#
31+ public sealed class Car : Identifiable <int >
32+ {
33+ [HasOne ]
34+ public Engine Engine { get ; set ; }
35+ }
36+
37+ public sealed class Engine : Identifiable <int >
38+ {
39+ [HasOne ]
40+ public Car Car { get ; set ; }
41+ }
42+
43+ public sealed class AppDbContext : DbContext
44+ {
45+ protected override void OnModelCreating (ModelBuilder builder )
46+ {
47+ builder .Entity <Car >()
48+ .HasOne (car => car .Engine )
49+ .WithOne (engine => engine .Car )
50+ .HasForeignKey <Car >()
51+ .IsRequired ();
52+ }
53+ }
54+ ```
55+
56+ Which results in EF Core generating the next database objects:
57+ ``` sql
58+ CREATE TABLE "Engine " (
59+ " Id" integer GENERATED BY DEFAULT AS IDENTITY,
60+ CONSTRAINT " PK_Engine" PRIMARY KEY (" Id" )
61+ );
62+ CREATE TABLE "Cars " (
63+ " Id" integer NOT NULL ,
64+ CONSTRAINT " PK_Cars" PRIMARY KEY (" Id" ),
65+ CONSTRAINT " FK_Cars_Engine_Id" FOREIGN KEY (" Id" ) REFERENCES " Engine" (" Id" )
66+ ON DELETE CASCADE
67+ );
68+ ```
69+
70+ That mechanism does not make sense for JSON: API , because patching a relationship would result in also
71+ changing the identity of a resource. Naming the foreign key explicitly fixes the problem by forcing to
72+ create a foreign key column.
73+
74+ ``` c#
75+ protected override void OnModelCreating (ModelBuilder builder )
76+ {
77+ builder .Entity <Car >()
78+ .HasOne (car => car .Engine )
79+ .WithOne (engine => engine .Car )
80+ .HasForeignKey <Car >(" EngineId" ) // Explicit foreign key name added
81+ .IsRequired ();
82+ }
83+ ```
84+
85+ Which generates the correct database objects:
86+ ``` sql
87+ CREATE TABLE "Engine " (
88+ " Id" integer GENERATED BY DEFAULT AS IDENTITY,
89+ CONSTRAINT " PK_Engine" PRIMARY KEY (" Id" )
90+ );
91+ CREATE TABLE "Cars " (
92+ " Id" integer GENERATED BY DEFAULT AS IDENTITY,
93+ " EngineId" integer NOT NULL ,
94+ CONSTRAINT " PK_Cars" PRIMARY KEY (" Id" ),
95+ CONSTRAINT " FK_Cars_Engine_EngineId" FOREIGN KEY (" EngineId" ) REFERENCES " Engine" (" Id" )
96+ ON DELETE CASCADE
97+ );
98+ CREATE UNIQUE INDEX "IX_Cars_EngineId " ON " Cars" (" EngineId" );
99+ ```
100+
23101## HasMany
24102
25103This exposes a to-many relationship.
0 commit comments