在 entity framework 中添加具有相同 table 的第二个一对一关系

Adding a second one-to-one relationship with the same table in entity framework

我正在进行代码优先 entity framework 设计。

我有一个 table,帐户,其中有一个 属性,主管:

public class Account
{
  public int Id { get; set; }
  public Account Supervisor { get; set; }
}

效果很好。

但是,我希望在 class 中添加一位候补主管:

public class Account
{
  public int Id { get; set; }
  public Account Supervisor { get; set; }
  public Account AlternateSupervisor { get; set; }
}

当我 运行 添加迁移 AddAlternateSupervisor 时,生成的代码为我提供了以下内容:

public partial class AddAlternateSupervisor : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropForeignKey(
            name: "FK_Accounts_Accounts_SupervisorId",
            table: "Accounts");

        migrationBuilder.DropIndex(
            name: "IX_Accounts_SupervisorId",
            table: "Accounts");

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

        migrationBuilder.CreateIndex(
            name: "IX_Accounts_AlternateSupervisorId",
            table: "Accounts",
            column: "AlternateSupervisorId",
            unique: true,
            filter: "[AlternateSupervisorId] IS NOT NULL");

        migrationBuilder.AddForeignKey(
            name: "FK_Accounts_Accounts_AlternateSupervisorId",
            table: "Accounts",
            column: "AlternateSupervisorId",
            principalTable: "Accounts",
            principalColumn: "Id",
            onDelete: ReferentialAction.Restrict);
    }
    // snip
}

如您所见,EF 正在尝试将我的引用从 Supervisor 重命名为 AlternateSupervisor。我不想这样,我希望 Supervisor 和 AlternateSupervisor 都引用其他帐户。

我知道 EF 无法处理多个多对多关系,但这些是一对一关系。我似乎无法找到有关 EF 为何生成这样的迁移的任何信息。

那么为什么 Entity Framework 试图将 Supervisor 重命名为 AlternateSupervisor 以及如何强制它生成两个链接?

编辑:这个问题已经按照最初的要求得到了回答。但是,我想补充一点,正如所问的那样,这个问题在领域内并没有多大意义。谁听说过一个账户只能监管另一个账户?该关系是一对多关系,通过使用 WithMany 而不是 WithOne 来解决。

EF Core 无法按照惯例将多个 one-to-one 映射到同一实体。您必须使用 Fluent API 执行以下操作:

你的 Account class:

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

    public int SupervisorId { get; set; }
    public Account Supervisor { get; set; }

    public int AlternateSupervisorId { get; set; }
    public Account AlternateSupervisor { get; set; }
}

然后在DbContextOnModelCreating如下:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
     base.OnModelCreating(modelBuilder);

     modelBuilder.Entity<Account>().HasOne(a => a.Supervisor).WithOne()
            .HasForeignKey<Account>(a => a.SupervisorId).OnDelete(DeleteBehavior.Restrict);

      modelBuilder.Entity<Account>().HasOne(a => a.AlternateSupervisor).WithOne()
            .HasForeignKey<Account>(a => a.AlternateSupervisorId).OnDelete(DeleteBehavior.Restrict);
 }

现在一切都会按预期生成!

注意:为了便于阅读,我已将 SupervisorIdAlternateSupervisorId 外键明确添加到 Account 模型 class 中。如果您不明确需要这些,那么 Fluent API 配置应如下所示:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
     base.OnModelCreating(modelBuilder);

     modelBuilder.Entity<Account>().HasOne(a => a.Supervisor)
                  .WithOne().OnDelete(DeleteBehavior.Restrict);

      modelBuilder.Entity<Account>().HasOne(a => a.AlternateSupervisor)
                  .WithOne().OnDelete(DeleteBehavior.Restrict);
 }