3

我正在使用实体框架开发一个简单的 MVC 应用程序来跟踪羽毛球联赛的分数。我有以下两个课程:

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.

任何帮助,将不胜感激。

4

4 回答 4

2

我不确定该设计是否可以按您希望的方式工作。如果你制作了一个新的“Score”实体来将玩家与这样的游戏联系起来会怎样:

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; }
}
于 2013-01-22T17:56:12.113 回答
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);

    }
于 2013-01-22T13:35:56.133 回答
0

请试试:

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

使用代码优先 API,您需要指定导航属性,就virtual好像您想使用延迟加载一样。请参阅C# EF Code First 虚拟关键字,它有什么作用?

于 2013-01-22T12:48:41.107 回答
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 字符串输出所有数据,它将加载所有游戏。如果没有,它不会打扰,因为它会认为你不需要任何游戏来展示。

于 2013-01-22T13:44:22.237 回答