EF 模型。导航属性只能参与单个关系

And*_*rey 11 c# entity-framework entity-framework-core

我有这样的实体,它们是紧密相连的。

public class Game
{
    public int Id { get; set; }

    public int FirstTeamId { get; set; }
    public Team FirstTeam { get; set; }
    public int SecondTeamId { get; set; }
    public Team SecondTeam { get; set; }

    public Stadium Stadium { get; set; }
    public DateTime Date { get; set; }

    public GameStatus Result { get; set; }

    public Game(DateTime date , GameStatus result )
    {
        Date = date;
        Result = result;
    }
}

public class Player
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public DateTime Birthday { get; set; }
    public PlayerStatus Status { get; set; }
    public PlayerHealthStatus HealthStatus { get; set; }
    public int Salary { get; set; }
    public int TeamId { get; set; }
    public Team Team { get; set; }

    public Player(string name , string surname, DateTime birthday, PlayerStatus status, PlayerHealthStatus healthStatus, int salary)
    {
        Name = name;
        Surname = surname;
        Birthday = birthday;
        Status = status;
        HealthStatus = healthStatus;
        Salary = salary;
    }

}

public class Stadium
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Capacity { get; set; }
    public int PriceForPlace { get; set; }

    public Stadium(string name, int capacity, int priceForPlace)
    {
        Name = name;
        Capacity = capacity;
        PriceForPlace = priceForPlace;
    }
}

public class Team
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Player> Players { get; set; }

    public List<Game> Games { get; set; }

    public Team(string name)
    {
        Name = name;
    }

    public Team(string name, List<Player> players) : this(name)
    {
        Players = players;

    }
}
Run Code Online (Sandbox Code Playgroud)

在我的 Context 类中,我试图描述类之间的关系。但有些事情是不正确的。

public class ApplicationContext : DbContext
{
    public DbSet<Player> Players { get; set; }
    public DbSet<Game> Games { get; set; }
    public DbSet<Team> Teams { get; set; }
    public DbSet<Stadium> Stadiums { get; set; }

    public ApplicationContext()
    {
        Database.EnsureCreated();
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Server=best-komp;Database=FootballApplicationDataBase;Trusted_Connection=True;");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Player>()
            .HasOne(p => p.Team)
            .WithMany(t => t.Players)
            .HasForeignKey(p => p.TeamId)
            .HasPrincipalKey(t => t.Id);
        modelBuilder.Entity<Team>()
            .HasMany(p => p.Players)
            .WithOne(p => p.Team)
            .HasForeignKey(p => p.TeamId)
            .HasPrincipalKey(t => t.Id);

        modelBuilder.Entity<Game>()
            .HasOne(g => g.FirstTeam)
            .WithMany(t => t.Games)
            .HasForeignKey(t => t.FirstTeamId)
            .HasPrincipalKey(t => t.Id);
        modelBuilder.Entity<Game>()
            .HasOne(g => g.SecondTeam)
            .WithMany(t => t.Games)
            .HasForeignKey(t => t.SecondTeamId)
            .HasPrincipalKey(t => t.Id);


    }
}
Run Code Online (Sandbox Code Playgroud)

这段代码有什么问题?因为我有“导航属性只能参与单个关系”。当我尝试对我的 ApplicationContext 做一些事情时出错。

Ger*_*old 17

你不能重复使用Team.Games的逆属性都Game.FirstTeamTeam.SecondTeam。想一想,如果将比赛添加到Team.Games,EF 怎么知道它是哪支球队,第一还是第二?

您需要两个集合来描述关系。这也是为类模型添加更多含义的机会。例如(仅修改代码):

public class Game
{
    ...
    public int HomeTeamId { get; set; }
    public Team HomeTeam { get; set; }
    public int AwayTeamId { get; set; }
    public Team AwayTeam { get; set; }
}

public class Team
{
    ...
    public List<Game> HomeGames { get; set; }
    public List<Game> AwayGames { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

对于一支球队来说,区分主客场比赛是有意义的,例如比较两种类型比赛的结果。

和映射:

modelBuilder.Entity<Game>()
    .HasOne(g => g.HomeTeam)
    .WithMany(t => t.HomeGames)
    .HasForeignKey(t => t.HomeTeamId)
    .HasPrincipalKey(t => t.Id);
modelBuilder.Entity<Game>()
    .HasOne(g => g.AwayTeam)
    .WithMany(t => t.AwayGames)
    .HasForeignKey(t => t.AwayTeamId).OnDelete(DeleteBehavior.NoAction)
    .HasPrincipalKey(t => t.Id);
Run Code Online (Sandbox Code Playgroud)

如果使用 Sql Server,则此删除行为指令是必要的,以防止不允许的多个级联路径。