Как выполнить двустороннее сопоставление EF Core One-to-One с обоими внешними ключами? - PullRequest
1 голос
/ 26 марта 2020

(Вроде как этот старый пост SO , но для EF Core 2 или 3)

Когда я отображаю два независимых объекта, которые имеют необязательный двунаправленный 1-к-1 при переходе друг к другу в миграции, генерируемой EF Core, отсутствует один из внешних ключей, которые я ожидаю увидеть.

У меня есть следующие классы:

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

        public ClassTwo ClassTwo { get; set; }
        public int? ClassTwoId { get; set; }
    }

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

        public ClassOne ClassOne { get; set; }
        public int? ClassOneId { get; set; }
    }

И следующее определение сопоставления :

    public class ClassOneDbConfiguration : IEntityTypeConfiguration<ClassOne>
    {
        public void Configure(EntityTypeBuilder<ClassOne> builder)
        {
            builder.HasOne(e => e.ClassTwo)
                    .WithOne(e => e.ClassOne)
                    .HasForeignKey<ClassTwo>(e => e.ClassOneId)
                    .OnDelete(DeleteBehavior.SetNull);

            builder.HasIndex(e => e.ClassTwoId).IsUnique();
        }
    }

    public class ClassTwoDbConfiguration : IEntityTypeConfiguration<ClassTwo>
    {
        public void Configure(EntityTypeBuilder<ClassTwo> builder)
        {
            builder.HasOne(e => e.ClassOne)
                    .WithOne(e => e.ClassTwo)
                    .HasForeignKey<ClassOne>(e => e.ClassTwoId)
                    .OnDelete(DeleteBehavior.SetNull);

            builder.HasIndex(e => e.ClassOneId).IsUnique();
        }
    }

Миграция, сгенерированная dotnet-ef migrations add CreateLinks, дает (для упрощения я создал таблицы в отдельной миграции):

            migrationBuilder.AddColumn<int>(
                name: "ClassOneId",
                table: "EntitiesTwo",
                nullable: true);

            migrationBuilder.AddColumn<int>(
                name: "ClassTwoId",
                table: "EntitiesOne",
                nullable: true);

            migrationBuilder.CreateIndex(
                name: "IX_EntitiesTwo_ClassOneId",
                table: "EntitiesTwo",
                column: "ClassOneId",
                unique: true);

            migrationBuilder.CreateIndex(
                name: "IX_EntitiesOne_ClassTwoId",
                table: "EntitiesOne",
                column: "ClassTwoId",
                unique: true);

            migrationBuilder.AddForeignKey(
                name: "FK_EntitiesOne_EntitiesTwo_ClassTwoId",
                table: "EntitiesOne",
                column: "ClassTwoId",
                principalTable: "EntitiesTwo",
                principalColumn: "Id",
                onDelete: ReferentialAction.SetNull);

Где находится создание внешнего ключа для таблицы EntitiesTwo? Без него у меня не может быть ON CASCADE SET NULL, и я могу получить недействительные данные в моей БД.

Конечно, я могу гарантировать ссылочную целостность в моем коде, но могу ли я иметь внешний ключ в БД как хорошо?

...