Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework child objects not populating

I have a simple model which when I run the website in the debugger the entity framework does not correctly populate the model.

The model is simple:

public class Team
{
    /// <summary>
    ///     Constructor required for the EntityFramework to create the object.
    /// </summary>
    private Team()
    {            
    }

    public Team(string name, ApplicationUser owner)
    {
        Name = name;
        Owner = owner;
    }

    [Required]
    public int Id { get; private set; }

    [Required]
    public string Name { get; private set; }

    [Required]
    public ApplicationUser Owner { get; private set; }

    [Required]
    public List<TeamMembership> Members { get; set; }
}


public class TeamMembership
{
    /// <summary>
    ///     Constructor for the EntityFramework
    /// </summary>
    private TeamMembership()
    {
    }

    public TeamMembership(ApplicationUser user, MembershipStatus status)
    {
        User = user;
        Status = status;
    }

    [Required]
    public ApplicationUser User { get; private set; }

    [Required]
    public MembershipStatus Status { get; set; }

    [Required]
    public int Id { get; private set; }
}

Where ApplicationUser is the default class generated by the ASP MVC 5 membership infrastructure.

When I run my tests (Specflow), which create a new LocalDb database with a unique id for each test and runs the migrations on that db, then the entity framework correctly populates my Team and the Owner.

However when I run the website and try and interact with the application then my Team is not fully populated, because the Owner is null and Members is not populated. But the owner ID is set correctly in the database and the query seems ok. The queries executed during the test and the running of the app seem the same.

Why might this be and how might I start to debug the issue?

I feel like I am missing something simple.

like image 721
Sam Holder Avatar asked Feb 06 '14 19:02

Sam Holder


1 Answers

You probably need to add .Include() to your query, which isn't shown in your question, but should look something like this:

var query = context.Teams.Include(x => x.Owner).Include(x => x.Members).Where( ... );

EF will only load the top-level entities, but not the entities referenced by it until they're needed (lazy loading). If you haven't disposed of the context, simply attempting to access those navigation properties should cause them to load from the database, but this won't happen if the context has been disposed of.

.Include() will inform EF that those navigation properties need to be eagerly loaded along with the referencing entity.

See this MSDN page for more detail about lazy/eager loading and how to control it.

like image 151
Steve Avatar answered Oct 14 '22 21:10

Steve