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

亡梦爱人 提交于 2020-04-17 10:03:31

问题


I am doing code-first entity framework design.

I have a table, Account, which has a property, Supervisor:

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

This works beautifully.

However, I wish to add an alternate supervisor to the class:

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

When I run Add-Migration AddAlternateSupervisor, the generated code gives me the following:

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
}

As you can see, EF is trying to rename my reference from Supervisor to AlternateSupervisor. I don't want that, I want both Supervisor and AlternateSupervisor to reference other accounts.

I know that EF can't handle multiple many-to-many relationships, but these are one to one relationships. I can't seem to find any information on why EF is generating the migration like this.

So why is Entity Framework trying to rename Supervisor to AlternateSupervisor and how can I force it to generate both links?

EDIT: This question was answered as initially asked. However, I would like to add that as asked the question doesn't really make much domain sense. Who ever heard of an account that could only ever supervise exactly one other account? The relationship is a one to many relationship, which is resolved by the use of WithMany instead of WithOne.


回答1:


EF Core cannot map multiple one-to-one with the same entity by convention. You have to do it with Fluent API as follows:

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

Then in the OnModelCreating of the DbContext as follows:

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

Now everything will generate as expected!

Note: I have added SupervisorId and AlternateSupervisorId foreign key explicitly to the Account model class for readability. If you don't want these explicitly then Fluent API configuration should be as follows:

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


来源:https://stackoverflow.com/questions/55252077/adding-a-second-one-to-one-relationship-with-the-same-table-in-entity-framework

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!