EF 4.1 Code First映射一个表中的两列列表

时间:2011-07-03 04:14:35

标签: entity-framework-4.1 ef-code-first

我有一个问题,想弄清楚如何使这项工作适用于EF 4.1 Code First。我环顾四周,找到了similar problem,但我无法让它为我工作,听起来这个人也没有得到回答。

以下是相关两个对象的简化版本。

public class Team
{
  public int TeamId {get; set;}
  public virtual IList<Game> Games {get; set;}
}

public class Game
{
  public int GameId {get; set; }
  public int AwayTeamId {get; set;}
  public int HomeTeamId {get; set;}

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

这是我注册FK的代码

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Game>()
        .HasRequired(a => a.HomeTeam)
        .WithMany()
        .HasForeignKey(u => u.HomeTeamId).WillCascadeOnDelete(false);

    modelBuilder.Entity<Game>()
        .HasRequired(a => a.AwayTeam)
        .WithMany()
        .HasForeignKey(u => u.AwayTeamId).WillCascadeOnDelete(false);
}

我想带回一个团队所在的所有游戏(主场或客场)。现在,EF正在我的数据库中创建一个永远不会被填充的TeamId列。如果我想要的是不可能的,那么我可以做HomeGames和AwayGames的列表以及另外两个游戏的列表,但是如果可能的话我想尽量避免它。我还在学习这个,所以任何额外的解释或提示都会受到赞赏。

2 个答案:

答案 0 :(得分:1)

你所要求的EF是一个只读集合,即添加操作对于这样的集合是没有意义的,因为EF不知道要插入哪个表,我认为这是不受支持的。

根据你的问题描述判断,我会像你自己的建议一样,并创建一个方法,如GetGames(),它将返回一组联合的主场和客场比赛。我认为无论如何这在概念上都是清洁的。

答案 1 :(得分:0)

EF无法将两个关系映射到单个导航属性。您的其他TeamId列已创建,因为Games导航属性被视为单独的关系(您的映射表明HomeTeamAwayTeam都不是该关系的一部分)所以您指示了EF为你创造三种关系。

您必须以这种方式定义模型:

public class Team
{
  public int TeamId {get; set;}
  public virtual ICollection<Game> HomeGames { get; set; }
  public virtual ICollection<Game> AwayGames { get; set; }
}

映射必须是:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Game>()
        .HasRequired(a => a.HomeTeam)
        .WithMany(t => t.HomeGames)
        .HasForeignKey(u => u.HomeTeamId).WillCascadeOnDelete(false);

    modelBuilder.Entity<Game>()
        .HasRequired(a => a.AwayTeam)
        .WithMany(t => t.AwayGames)
        .HasForeignKey(u => u.AwayTeamId).WillCascadeOnDelete(false);
}

现在,如果你想要所有团队的游戏,你可以简单地使用:

var games = team.HomeGames.Concat(team.AwayGames);

您可以将此包装到返回IEnumerable的方法中,或者将其包含在只返回IEnumerable的getter的属性中。