首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在实体框架中添加与同一表的第二个一对一关系

在实体框架中添加与同一表的第二个一对一关系
EN

Stack Overflow用户
提问于 2019-03-20 08:55:46
回答 1查看 2.4K关注 0票数 4

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

我有一个表Account,它有一个属性Supervisor:

代码语言:javascript
代码运行次数:0
运行
复制
public class Account
{
  public int Id { get; set; }
  public Account Supervisor { get; set; }
}

这个很好用。

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

代码语言:javascript
代码运行次数:0
运行
复制
public class Account
{
  public int Id { get; set; }
  public Account Supervisor { get; set; }
  public Account AlternateSupervisor { get; set; }
}

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

代码语言:javascript
代码运行次数:0
运行
复制
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。我不想这样,我希望主管和AlternateSupervisor都引用其他帐户。

我知道EF不能处理多对多关系,但这些是一对一的关系。我似乎找不到任何关于EF为什么会产生这样的迁移的信息。

那么为什么实体框架试图将Supervisor重命名为AlternateSupervisor,以及如何强制它同时生成两个链接?

编辑:此问题已按最初询问的方式回答。然而,我想补充的是,正如所问的那样,这个问题并没有太多的领域意义。谁听说过一个帐户只能管理另一个帐户?该关系是一对多关系,通过使用WithMany而不是WithOne来解决。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-20 09:37:17

按照约定,EF核心不能将多个one-to-one映射到同一实体。您必须使用Fluent API执行此操作,如下所示:

您的Account类:

代码语言:javascript
代码运行次数:0
运行
复制
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中,如下所示:

代码语言:javascript
代码运行次数:0
运行
复制
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);
 }

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

注意:为了提高可读性,我在Account模型类中显式地添加了SupervisorIdAlternateSupervisorId外键。如果您不需要这些显式配置,则Fluent API配置应如下所示:

代码语言:javascript
代码运行次数:0
运行
复制
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);
 }
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55252077

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档