Matt Hyde
Matt Hyde

Reputation: 1650

MVC4 tutorial - Eager loading of a property of a foreign key object, that has itself been eager loaded

I am working with MVC4 and EF5, and I have been working through the Contoso University tutorial on this page: http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application

Relevant parts of the The Entity Framework model classes:

public class Student
{
    public int StudentID { get; set; }
    public string LastName { get; set; }
    public virtual ICollection<Enrollment> Enrollments { get; set; }
}

public enum Grade { A,B,C,D,F}
public class Enrollment
{
    public int EnrollmentID { get; set; }
    public int CourseID { get; set; }
    public int StudentID { get; set; }
    public Grade? Grade { get; set; }
    public Course Course { get; set; }
    public Student Student { get; set; }
}

public class Course
{
    public int CourseID { get; set; }
    public string Title { get; set; }
    public virtual ICollection<Enrollment> Enrollments { get; set; }
}

In the Controller:

public ActionResult Details(int id = 0) {
    Student student = db.Students.Find(id);
    return View(student);
}

The relevant bit of the view:

@foreach (var item in Model.Enrollments) {
    <tr>
    <td>
        @Html.DisplayFor(modelItem => item.Course.Title) //this does not display as Course is null
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Grade)
    </td>
    </tr>
}

Contrary to what the tutorial says, for me the view does not display the Course Title, it only shows the Grade.

Course Title    Grade
                A
                C
                B

Debugging shows that the Course property (representing the foreign key to Course) is null. In other words, for each Student, the Enrollments collection is loaded, but those enrollments have not loaded their Course property. I cannot work out how to use Eager Loading to load the Course property of each Enrollment. How do I get the Course Title to display in the view?

I have found that a hard coded "Include" string works (in the Controller):

Student student = db.Students.Where(x => x.StudentID == id).Include("Enrollments.Course").Single();

But I cannot work out how to do it with a lambda function or any other function.

I have tried the following with no success:

Student student = db.Students.Where(x => x.StudentID == id).Include(y => y.Enrollments.Course).Single();
Student student = db.Students.Where(x => x.StudentID == id).Include(y => y.Enrollments).Include(z => z.Enrollments.Course).Single();

Upvotes: 0

Views: 1136

Answers (1)

WannaCSharp
WannaCSharp

Reputation: 1898

Dont forget this in your c# file:

using System.Data.Entity;

EDIT:

Or just mark your Course property as virtual for lazy loading

public class Enrollment
{

        public virtual Course Course { get; set; }
        public virtual Student Student { get; set; }
}

Upvotes: 2

Related Questions