在实体框架中与同一表添加第二个一对一关系 [英] Adding a second one-to-one relationship with the same table in entity framework

查看:81
本文介绍了在实体框架中与同一表添加第二个一对一关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在执行代码优先的实体框架设计。

I am doing code-first entity framework design.

我有一个表Account,该表具有属性Supervisor:

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

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

这很不错。

但是,我希望为班级增加一名候补主管:

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

当我运行Add-Migration AddAlternateSupervisor时,生成的代码为我提供了以下内容:

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
}

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

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.

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

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.

那么,为什么Entity Framework试图将Supervisor重命名为AlternateSupervisor,以及如何强制

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

编辑:按最初询问的方式回答了这个问题。不过,我想补充一点,即这个问题并没有多大意义。谁曾听说过只能监督另一个帐户的帐户?该关系是一对多关系,可以通过使用WithMany代替WithOne来解决。

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.

推荐答案

EF Core无法映射按照惯例,同一实体具有多个一对一。您必须使用 Fluent API 来做到这一点,

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

您的帐户类:

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

然后在 OnModelCreating DbContext 的c>如下:

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!

注意:我已将 SupervisorId AlternateSupervisorId 外键明确添加到 Account 模型类以提高可读性。如果您不想明确地使用它们,那么 Fluent API 的配置应如下所示:

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

这篇关于在实体框架中与同一表添加第二个一对一关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆