Entity Framework Many of the many between the two classes

I am working on a simple MVC application using Entity Framework to track badminton league scores. I have the following two classes:

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; }
}

      

and

public class Player
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string Surname { get; set; }
    public List<Game> Games { get; set; }
}

      

The problem is when I have a player instance the Games property returns an empty list. When I request my player list I use the following: -

var players = badmintonDB.Players.Include("Games").ToList();

      

From a search on SO, I tried to override OnModelCreating

. I have tried the following with Map()

and without it. This creates another table in my database, but it contains no records.

    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);

    }

      

I don't see where I am going wrong, I need to rethink the design of my POCO or if I have the syntax wrong when overridden OnModelCreating

.

Any help would be appreciated.

+3


source to share


4 answers


I'm not sure if this project can work the way you want it to. What if you created a new Score object to associate players with these games:



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; }
}

      

+2


source


Update:
After thinking more about it, I'm not sure if this can be done with automatic navigation properties at all. The reason is this: you have two foreign keys in Game

. Therefore, in order for the player to load their list of games, EF would have to create a selection on two foreign keys.

Old answer (which I believe to be wrong now):
EF is trying to auto-detect navigation properties. Perhaps it is not, since it Game

has two Player

.



Declare the navigation yourself:

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);

    }

      

+1


source


Try:

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

      

With the first code API, you need to specify the navigation properties as virtual

if you want to use lazy loading. See C # EF Code First virtual keyword, what does it do?

0


source


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;

should return all players with all their associated games if lazy loading is enabled and you haven't changed any of your relationships as you did with Map();

.

But be careful when loading data with lazy loading, which really depends on what you are outputting. If you, for example, output all data in a JSON string, it will load all games. If not, it doesn't bother as it will think that you won't need any games.

0


source







All Articles