Parkyster
Parkyster

Reputation: 155

Entity framework navigation property is null

I have two models using Entity Framework.

public class Player
{

    public int PlayerId { get; set; }
    public string Name { get; set; }
    public string Sex { get; set; }
    public string Plays { get; set; }
    public string FavouriteSurface { get; set; }

}

public class SinglesMatch
{
    public int SinglesMatchId { get; set; }
    public int Player1Id { get; set; }
    public int Player2Id { get; set; }
    public int PlayerIdWinner { get; set; }
    public DateTime Date { get; set; }
    public string Venue { get; set; }
    public string Score { get; set; }
    public List<Player> Players { get; set; } 
}

I am using the below code to attempt to display the Name of the player, based on the PlayerId in the SinglesMatch model matching the PlayerID from the Player model.

      @foreach (var item in @Model)
                    {

                        <ul id="Players" class="bg-success"></ul>
                        <br/>
                        <h3>Date - @Html.DisplayFor(@modelItem => item.Date)</h3>
                        <li>Venue - @Html.DisplayFor(@modelItem => item.Venue)</li>
                        <li>Player 1 - @Html.DisplayFor(@modelItem => item.Players.First(p => p.PlayerId == item.Player1Id).Name)</li>
                        <li>Player 2 - @Html.DisplayFor(@modelItem => item.Players.First(p => p.PlayerId == item.Player2Id).Name)</li>
                        <li>Score- @Html.DisplayFor(@modelItem => item.Score)</li>



                    }

Upon debugging, the navigation property is always showing as null when the model is retrieved from my repository.

Am I using the navigation property in the correct fashion ? is there a problem with my query ?

Edit to include DbContext:

    public TennisTrackerContext() : base("name=TennisTrackerContext")
    {

    }

    public DbSet<Player> Players { get; set; }
    public DbSet<PlayerRecord> PlayerRecords { get; set; }
    public DbSet<SinglesMatch> SinglesMatches { get; set; }
    public DbSet<DoublesMatch> DoublesMatches { get; set; }
    public DbSet<Venue> Venues { get; set; } 
}

}

Upvotes: 0

Views: 291

Answers (2)

MIKE
MIKE

Reputation: 1059

You need to add a bridge table. Sql will create this automatically but you won't have access to the variables unless you create it in c#.

public class Player
    {
        public int PlayerId { get; set; }
        public string Name { get; set; }
        public string Sex { get; set; }
        public string Plays { get; set; }
        public string FavouriteSurface { get; set; }
        List<PlayerInMatch> Matches { get; set; }

        public Player()
        {
            Matches = new List<PlayerInMatch>();
        }
    }

    public class PlayerInMatch
    {
        public int Id { get; set; }
        public int PlayerId { get; set; }
        [ForeignKey("PlayerId")]
        public Player Player { get; set; }
        public int SinglesMatchId { get; set; }
        [ForeignKey("SinglesMatchId")]
        public SinglesMatch SinglesMatch { get; set; }

    }

    public class SinglesMatch
    {
        public int SinglesMatchId { get; set; }
        public int PlayerIdWinner { get; set; }
        public DateTime Date { get; set; }
        public string Venue { get; set; }
        public string Score { get; set; }
        public List<PlayerInMatch> Players { get; set; }

        public SinglesMatch()
        {
            Players = new List<PlayerInMatch>();
        }
    }

    static void Main(string[] args)
    {
        var match = new SinglesMatch();
        match.Players.Select(c => c.Player.Name);
    }

Upvotes: 1

Alexander Derck
Alexander Derck

Reputation: 14498

You need to make your navigation property virtual to enable lazy/eager loading:

public class SinglesMatch
{
public int SinglesMatchId { get; set; }
public int Player1Id { get; set; }
public int Player2Id { get; set; }
public int PlayerIdWinner { get; set; }
public DateTime Date { get; set; }
public string Venue { get; set; }
public string Score { get; set; }

public virtual List<Player> Players { get; set; } 
}

Also, did you define the relationship between SinglesMatch and Singles in fluent api?

EDIT: I see you don't have any relations mapped through annotations or fluent api whatsoever, I suggest you take a look at this:

https://msdn.microsoft.com/en-us/data/jj591617.aspx

Upvotes: 0

Related Questions