Auto-generated FK relations in EF Core - how to made them non-nullable

.net-core domain-driven-design entity-framework-core entity-framework-core-3.1 entity-framework-core-migrations

Question

I have the following model:

public class Child
{
    public int Id { get; set; }
}

public class Parent
{
    public int Id { get; set; }
    public List<Child> Childs { get; set; }
}

Without any further instructing, EF Core 3.1 automatically infers the reference relation between Parent and Child, and generates the following migration creating nullable foreign key column on Child table:

....

migrationBuilder.CreateTable(
        name: "Child",
        columns: table => new
        {
            Id = table.Column<int>(nullable: false)
                .Annotation("SqlServer:Identity", "1, 1"),
            ParentId = table.Column<int>(nullable: true)   // <--- !!
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_Child", x => x.Id);
            table.ForeignKey(
                name: "FK_Child_Parent_ParentId",
                column: x => x.ParentId,
                principalTable: "Parent",
                principalColumn: "Id",
                onDelete: ReferentialAction.Restrict);
        });

resulting in the schema below:

enter image description here

I need the FK to be non-nullable though. How to enforce EF to do it without changing the model (without the necessity of introducing artificial properties only to define underlying storage relations)?


PS: In particular I want to avoid abusing the model by introducing 2-way references, only to be able to express what I need, e.g.

public class Child
{
    public int Id { get; set; }
    public Parent Parent { get; set; }   // <--- not acceptable
}

modelBuilder.Entity<Parent>()
    .HasMany(p => p.Childs)
    .WithOne(c => c.Parent)
    .IsRequired();   // <--- non-null

Is the manual interference into the migration code the only solution (doesn't it result in mismatch with the model snapshot then)?

1
1
1/18/2020 8:08:33 PM

Accepted Answer

Since the dependent entity has no reference navigation property on which to put [Required] attribute or use C# 8 non nullable reference type (e.g. Parent vs Parent?), and has no explicit FK property with non nullable type (e.g. int vs int?), the only remaining option is fluent API.

Relationship fluent API requires at least correct Has + With pair, and then in this particular case IsRequired() method:

modelBuilder.Entity<Parent>()
    .HasMany(e => e.Childs) // collection navigation property
    .WithOne() // no reference navigation property
    .IsRequired();
1
1/18/2020 1:48:22 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