我正在研究一个简单的MVC应用程序,使用Entity Framework跟踪羽毛球联赛的得分。我有以下两个类:
public class Game
{
public int Id { get; set; }
public Player Player1 { get; set; }
public Player Player2 { get; set; }
public int Player1Score { get; set; }
public int Player2Score { get; set; }
}
和
public class Player
{
public int Id { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
public List<Game> Games { get; set; }
}
我遇到的问题是当我有一个玩家实例时,Games属性返回一个空列表。当我请求我的球员名单时,我使用以下内容: -
var players = badmintonDB.Players.Include("Games").ToList();
从搜索SO开始,我试图覆盖OnModelCreating
。无论有没有Map()
,我都尝试了以下内容。这会在我的数据库中创建另一个表,但它不包含任何记录。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Player>().HasMany(p => p.Games).WithMany()
.Map(m =>
{
m.ToTable("PlayerGames");
m.MapLeftKey("Player_Id");
m.MapRightKey("Game_Id");
});
base.OnModelCreating(modelBuilder);
}
我无法看到我出错的地方,我是否需要重新考虑我的POCO的设计,或者在覆盖OnModelCreating
时我是否有错误的语法。
任何帮助都将不胜感激。
答案 0 :(得分:2)
我不确定该设计是否可以按您希望的方式工作。如果您创建了一个新的“分数”实体来将玩家与这样的游戏联系起来该怎么办:
public class Game
{
public int Id { get; set; }
public virtual ICollection<Score> Scores { get; set; }
}
public class Player
{
public int Id { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
public virtual ICollection<Score> Scores { get; set; }
}
public class Score
{
public int ScoreId { get; set; }
public virtual Player Player { get; set; }
public virtual Game Game { get; set; }
public int Score { get; set; }
}
答案 1 :(得分:1)
<强>更新强>
在考虑更多关于它的问题时,我不确定是否可以使用自动导航属性。原因是:Game
中有两个外键。因此,对于玩家加载其游戏列表,EF必须在两个外键上创建选择。
旧答案(我现在认为是错误的):
EF尝试自动检测导航属性。由于Game
有两个Player
,因此可能会失败。
自己声明导航:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder
.Entity<Game>()
.HasRequired(g => g.Player1)
.WithMany()
.WillCascadeOnDelete(false);
modelBuilder
.Entity<Game>()
.HasRequired(g => g.Player2)
.WithMany()
.WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
答案 2 :(得分:0)
请尝试:
public virtual List<Game> Games { get; set; }
使用代码优先API,如果要使用延迟加载,则需要将导航属性指定为virtual
。
见C# EF Code First virtual keyword, what does it do?
答案 3 :(得分:0)
public class Player
{
public Player()
{
this.Games = new List<Game>();
}
public int Id { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
public List<Game> Games { get; set; }
}
如果启用了延迟加载, var players = badmintonDB.Players;
应该返回所有与其关联的游戏的玩家,并且您没有像使用Map();
那样修改任何关系。
但是在使用延迟加载加载数据时要注意,这实际上取决于您输出的内容。如果你愿意,例如输出JSON字符串中的所有数据,它将加载所有游戏。如果没有,它就不会打扰,因为它会认为你不需要任何游戏来展示。