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

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

问题描述

我在做代码优先的实体框架设计.

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 不能按照约定将多个 one-to-one 映射到同一个实体.您必须使用 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:

您的Account 类:

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

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

Now everything will generate as expected!

注意:为了便于阅读,我已将 SupervisorIdAlternateSupervisorId 外键显式添加到 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天全站免登陆