【问题标题】:EF Core 2.2 - Two foreign keys to same tableEF Core 2.2 - 同一张表的两个外键
【发布时间】:2019-06-22 09:52:36
【问题描述】:

我遇到了与此处发布的问题类似的问题: Entity Framework Code First - two Foreign Keys from same table,但是它已经很老了,不适用于 Core,我无法得到适合我的建议。

基本上,我正在尝试创建一个夹具表,该表将有两个外键到团队表。赛程由主队和客队组成。不能有可为空的字段。

考虑一个有两支球队的比赛。

public class Fixture
{
    public int Id { get; set; }
    public Team HomeTeam { get; set; }
    public int HomeTeamId { get; set; }
    public Team AwayTeam { get; set; }
    public int AwayTeamId { get; set; }

    public virtual Team HomeTeam { get; set; }
    public virtual Team AwayTeam { get; set; }
}



public class Team
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public String Name { get; set; }
    public ICollection<Fixture> HomeFixtures { get; set; } = new List<Fixture>();
    public ICollection<Fixture> AwayFixtures { get; set; } = new List<Fixture>();
}

我得到了错误...

无法确定“团队”类型的导航属性“Fixture.HomeTeam”表示的关系。手动配置关系,或使用“[NotMapped]”属性或使用“OnModelCreating”中的“EntityTypeBuilder.Ignore”忽略此属性。

所以我尝试在数据库上下文中添加一些 OnModelCreating 代码:

protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Fixture>()
                    .HasOne(m => m.HomeTeam)
                    .WithMany(t => t.HomeFixtures)
                    .HasForeignKey(m => m.HomeTeamId)
                    .OnDelete(DeleteBehavior.Restrict);


        modelBuilder.Entity<Fixture>()
                    .HasOne(m => m.AwayTeam)
                    .WithMany(t => t.AwayFixtures)
                    .HasForeignKey(m => m.AwayTeamId)
                    .OnDelete(DeleteBehavior.Restrict);
    }

然后我得到了错误:

Introducing FOREIGN KEY constraint 'FK_Fixtures_Teams_HomeTeamId' on table 'Fixtures' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

谁能帮忙搞定这个设置?

谢谢。

【问题讨论】:

  • show Fixture 类中的导航属性重复(可能是拼写错误)。除此之外,模型 + 显示的流畅配置应该能产生你需要的东西。确保重新生成迁移,“循环或多级联路径”错误是当您使用.OnDelete(DeleteBehavior.Restrict)时,所以我猜您正在运行陈旧的迁移。
  • @IvanStoev 谢谢 - 这确实是一个陈旧的迁移。我删除了迁移,生成了一个新的迁移,并且在更新数据库之后它都按我预期的那样工作。感谢您的宝贵时间。

标签: asp.net-mvc foreign-keys entity-framework-core


【解决方案1】:
public class Fixture
{
    public int Id { get; set; }
    public int HomeTeamId { get; set; }
    public int AwayTeamId { get; set; }

    [ForeignKey("HomeTeamId")]
    public virtual Team HomeTeam { get; set; }

    [ForeignKey("AwayTeamId")]
    public virtual Team AwayTeam { get; set; }
}

这样导航就可以了。也正如@Ivan 所建议的那样,删除重复的 getter 和 setter。

【讨论】:

  • 这仍然是 EF Core 3.1 的可行答案,救了我!
【解决方案2】:

以下解决方案适用于 EF Core 3:

  1. 确保外键可以为空

  2. 指定删除的默认行为

    public class Match 
    { 
       public int? HomeTeamId { get; set; }
       public int? GuestTeamId { get; set; }
    
       public float HomePoints { get; set; }
       public float GuestPoints { get; set; }
       public DateTime Date { get; set; }
    
       public Team HomeTeam { get; set; }
       public Team GuestTeam { get; set; }
    }
    
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Match>()
                    .HasRequired(m => m.HomeTeam)
                    .WithMany(t => t.HomeMatches)
                    .HasForeignKey(m => m.HomeTeamId)
                    .OnDelete(DeleteBehavior.ClientSetNull);
    
        modelBuilder.Entity<Match>()
                    .HasRequired(m => m.GuestTeam)
                    .WithMany(t => t.AwayMatches)
                    .HasForeignKey(m => m.GuestTeamId)
                    .OnDelete(DeleteBehavior.ClientSetNull);
    }
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-30
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 2011-07-12
    相关资源
    最近更新 更多