1. ホーム
  2. c#

[解決済み】Entity Framework コードファースト - 同じテーブルから2つの外部キー

2022-03-31 02:31:22

質問

まずEFコードを使い始めたばかりで、このトピックに関しては全くの初心者です。

TeamsとMatchesの間にリレーションを作成したいと思いました。

1試合=2チーム(ホーム、ゲスト)、結果。

このようなモデルを作るのは簡単だと思い、コーディングを開始しました。

public class Team
{
    [Key]
    public int TeamId { get; set;} 
    public string Name { get; set; }

    public virtual ICollection<Match> Matches { get; set; }
}


public class Match
{
    [Key]
    public int MatchId { get; set; }

    [ForeignKey("HomeTeam"), Column(Order = 0)]
    public int HomeTeamId { get; set; }
    [ForeignKey("GuestTeam"), Column(Order = 1)]
    public int GuestTeamId { get; set; }

    public float HomePoints { get; set; }
    public float GuestPoints { get; set; }
    public DateTime Date { get; set; }

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

そして、例外が発生する。

参照関係は、許可されていない循環的な参照になります。[ 制約名 = Match_GuestTeam ]。

同じテーブルに対して2つの外部キーを持つ、このようなモデルを作成するにはどうしたらよいでしょうか?

どのように解決するのですか?

これを試してみてください。

public class Team
{
    public int TeamId { get; set;} 
    public string Name { get; set; }

    public virtual ICollection<Match> HomeMatches { get; set; }
    public virtual ICollection<Match> AwayMatches { get; set; }
}

public class Match
{
    public int MatchId { get; set; }

    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 virtual Team HomeTeam { get; set; }
    public virtual Team GuestTeam { get; set; }
}


public class Context : DbContext
{
    ...

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Match>()
                    .HasRequired(m => m.HomeTeam)
                    .WithMany(t => t.HomeMatches)
                    .HasForeignKey(m => m.HomeTeamId)
                    .WillCascadeOnDelete(false);

        modelBuilder.Entity<Match>()
                    .HasRequired(m => m.GuestTeam)
                    .WithMany(t => t.AwayMatches)
                    .HasForeignKey(m => m.GuestTeamId)
                    .WillCascadeOnDelete(false);
    }
}

主キーはデフォルトでマッピングされます。チームはマッチのコレクションを2つ持つ必要があります。2つのFKから参照される1つのコレクションを持つことはできません。マッチはカスケード削除なしでマップされます。これは、自己参照する多対多では削除が機能しないためです。