CularBytes
CularBytes

Reputation: 10321

Navigation Properties, Object not set to an instance of an object

I have found some solutions on this, but most were in winforms, wpf. Some solutions are about MVC, it just doesn't fix my problem.

I've created this by following this tutorial.

Controller

public class NewPageController : Controller
{
    private SchoolContext db = new SchoolContext();

    public ActionResult ABC()
    {

        var Students = db.Students;

        return View(Students);
    }
 }

Models:

public class Student
{
    public int StudentId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime EnrollmentDate { get; set; }
    //NavigationProperties
    public List<Enrollment> Enrollments { get; set; } 

}

public class Course
{
    public int CourseId { get; set; }
    public string CourseName { get; set; }
    public int TotalCredits { get; set; }
    //navigationProperties
    public List<Enrollment> Enrollments { get; set; } 
}

public class Enrollment
{
    public int EnrollmentId { get; set; }
    public int CourseId { get; set; }
    public int StudentId { get; set; }
    public decimal? Grade { get; set; } 

    //navigation properties
    public Student student { get; set; }
    public Course course { get; set; }
}

public class SchoolContext : DbContext
{
    public DbSet<Student> Students { get; set; }
    public DbSet<Course> Courses { get; set; }
    public DbSet<Enrollment> Enrollments { get; set; }
}

When following the tutorial, he explains how to create some sample data, using initializing. Now I am not really a fan of this, I'm still trying to understand how to do it.

I've done that, like this:

public class SchoolInitializer :DropCreateDatabaseIfModelChanges<SchoolContext>
{
    protected override void Seed(SchoolContext context)
    {
        var students = new List<Student>
        {
            new Student{FirstName = "James", LastName="Dean", EnrollmentDate = DateTime.Parse("10-01-2015")},
            new Student{FirstName = "Lison", LastName="Bergsma", EnrollmentDate = DateTime.Parse("05-01-2015")},
        };
        foreach(var temp in students)
        {
            context.Students.Add(temp);
        }
        context.SaveChanges();

        var courses = new List<Course>
        {
            new Course{CourseName = "Java", TotalCredits=4},
            new Course{CourseName = "C#", TotalCredits=4},
        };
        foreach (var temp in courses)
        {
            context.Courses.Add(temp);
        }
        context.SaveChanges();

        var enrollments = new List<Enrollment>
        {
            new Enrollment{StudentId=1,CourseId=1, Grade =3},
            new Enrollment{StudentId=1,CourseId=2, Grade =4},
        };
        foreach (var temp in enrollments)
        {
            context.Enrollments.Add(temp);
        }
        context.SaveChanges();

    }
}

Views

Here is where I get the exception, when I try to do the foreach for the item.Enrollments.

@model IEnumerable<ProjectName.Models.Student>

@foreach (var item in Model)
{
    <h2> Student : @item.FirstName @item.LastName</h2>
    foreach (var i in item.Enrollments)
    {
        <h2>Course: @i.course.CourseName</h2>
    }
    <br />
}

Like many suggested, I've tried making a constructor in the Models, and make a new instance of the Enrollments objects. When doing this, it didn't give me any errors, but it didn't load any data as well. Instead of sending the Students to the View page, I've tried sending the Enrollments, then calling the other classes/tables. Same story, error appears, creating constructor results in no errors but no data eater.

Upvotes: 1

Views: 980

Answers (3)

Milen
Milen

Reputation: 8877

Specify the related objects to include in the query results.

public class NewPageController : Controller
{
    private SchoolContext db = new SchoolContext();

    public ActionResult ABC()
    {

        var Students = db.Students.Include("Enrollments.course"); //edit by OP

        return View(Students);
    }
 }

Edit by OP:

I've edited above code and included below code for my solution.

@model IEnumerable<vergelijkCuracao.Models.Student>

@foreach (var item in Model)
{
    <h2> Student : @item.FirstName @item.LastName</h2>
    if (item.Enrollments != null)
    {
        foreach (var i in item.Enrollments)
        {
            <h2> Course : @i.course.CourseName</h2>
        }
    }

}

I have to remark, that the if check is not really required in this example, even though student 2 is not enrolled in any course, it doesn't give me any error, it just doesn't contain any data so the foreach loop will not be executed.

Upvotes: 1

Ammar Hamidou
Ammar Hamidou

Reputation: 205

@model IEnumerable<ProjectName.Models.Student>

@foreach (var item in Model)
{
    <h2> Student : @item.FirstName @item.LastName</h2>
    if (item.Enrollments!=null)
    {
       foreach (var i in item.Enrollments)
       {
          <h2>Course: @i.course.CourseName</h2>
       }
      <br />
    }
}

Upvotes: 1

Dany Ellement
Dany Ellement

Reputation: 226

Check that you actually initialized you DbContext in the Application_Start() method of

Global.asax.cs

protected void Application_Start(){
    Database.SetInitializer<SchoolContext>(new SchoolInitializer());
    AreaRegisration.RegisterAllAreas();
    ...
}

Upvotes: 0

Related Questions