Автоматически сгенерированные отношения FK в EF Core - как сделать их необнуляемыми - PullRequest
1 голос
/ 18 января 2020

У меня есть следующая модель:

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

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

Без дополнительных инструкций EF Core 3.1 автоматически выводит эталонное отношение между Parent и Child и генерирует следующую миграцию, создавая столбец внешнего ключа, допускающий нулевое значение в таблице Child:

....

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);
        });

, что приводит к схеме ниже:

enter image description here

Мне нужен FK для быть ненулевым хотя. Как заставить EF сделать это без изменения модели (без необходимости введения искусственных свойств только для определения базовых отношений хранения)?

PS: В частности, я хочу избежать злоупотребления моделью, вводя двухсторонние ссылки, только чтобы иметь возможность express, что мне нужно, например,

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

Является ли ручное вмешательство в код миграции единственным решение (не приводит ли это к несовпадению со снимком модели)?

1 Ответ

1 голос
/ 18 января 2020

Поскольку зависимый объект не имеет свойства навигации по ссылкам, для которого можно поставить атрибут [Required] или использовать C# 8 необнуляемый ссылочный тип (например, Parent против Parent?), и не имеет явного свойства FK с ненулевым значением тип (например, int против int?), единственным оставшимся параметром является свободный API.

Для API свободного отношения требуется как минимум правильная Has + With пара, а затем в данном конкретном случае IsRequired() метод:

modelBuilder.Entity<Parent>()
    .HasMany(e => e.Childs) // collection navigation property
    .WithOne() // no reference navigation property
    .IsRequired();
...