Owned entity foreign‑key column missing when owner property is nullable
0 reputation · 26 Oct 2024, 22:22 UTC
0 reputation · 26 Oct 2024, 22:22 UTC
Determine how EF Core decides whether to create a foreign‑key column for an owned type that references a property of its owner.
34275 reputation · 27 Oct 2024, 01:28 UTC
OwnsOne(..., b => b.HasForeignKey(...)) or OwnsOne(..., b => b.Property(p => p.OwnerId).IsRequired(false)) resolves ambiguous FK generation when multiple owned types reference the same owner property.EF Core maps owned types to the same table as the owner by default. When an owned type references a property of its owner (e.g., a navigation or scalar property), the FK column is created in the owned type's table representation. The nullability of that FK column follows the nullability of the referenced owner property: a nullable owner property produces a nullable FK column; a non-nullable owner property produces a non-nullable FK column.
If the owner entity has a composite primary key, EF Core may merge the owned type's FK into the existing key columns. This happens when the owned type does not declare its own primary key. The owned type then shares the owner's composite key, and no separate FK column appears. If the owned type does define a separate primary key (via HasKey in the owned type's configuration), a dedicated FK column is always created regardless of the owner's key structure.
When two or more owned types reference the same owner property, EF Core cannot infer which owned type owns the FK column, leading to ambiguous migrations or duplicate column errors. You must disambiguate by explicitly configuring the FK for each owned type.
OnModelCreating, configure each owned type with OwnsOne and chain HasForeignKey to point to a distinct property on the owned type:
modelBuilder.Entity<Owner>()
.OwnsOne(o => o.OwnedA, a =>
{
a.HasForeignKey("OwnerIdA");
a.Property("OwnerIdA").IsRequired(false); // nullable FK
})
.OwnsOne(o => o.OwnedB, b =>
{
b.HasForeignKey("OwnerIdB");
b.Property("OwnerIdB").IsRequired(false);
});
HasKey inside the owned type configuration:
.OwnsOne(o => o.OwnedA, a =>
{
a.HasKey("Id");
a.HasForeignKey("OwnerIdA");
});
.IsRequired(false)) to match. For non-nullable owner properties, omit IsRequired(false) or call .IsRequired().dotnet ef migrations script and inspect the generated SQL for the owned type's table. Confirm the FK column exists and its NULL/NOT NULL constraint matches expectations.dotnet ef database update), check the model snapshot (Migrations/...ModelSnapshot.cs) for the column's IsNullable attribute.Does the owned type define its own primary key (via HasKey or a key property), or does it rely on the owner's key? This determines whether a separate FK column is created or the FK is merged into a composite key.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.