简体   繁体   中英

Entity Framework 6 Lazy Loading doesn't work

I have created two model classes: Student and Exam .

Student:

class Student
{
    [Key]
    public int StudentId { get; set; }

    [Required, MaxLength(30)]
    public string FirstName { get; set; }

    [Required, MaxLength(50)]
    public string LastName { get; set; }

    [Required]
    public DateTime BirthDate { get; set; }

    public virtual ICollection<Exam> Exams { get; set; } 
}

Exam:

public enum Grade
{
    A, B, C, D, E, F
}
class Exam
{
    [Key]
    public int ExamId { get; set; }

    [Required]
    public Grade Grade { get; set; }

    [ForeignKey("Student"), Required]
    public int StudentId { get; set; }

    public virtual Student Student { get; set; }
}

But it seems Lazy Loading doesn't work, here's example how I retrieve data:

using (var context = new StudentContext())
{
    context.Configuration.LazyLoadingEnabled = true;
    context.Configuration.ProxyCreationEnabled = true;

    var student = context.Students.Single(s => s.LastName == "ABC");

    foreach (var exam in student.Exams)
    {
        Console.WriteLine($"{exam.ExamId}: {exam.Grade}");
    } 
    context.SaveChanges();
}

And I'm getting NullReferenceException when I try to access students.Exams property. What's wrong in my code?

The problem with my code is that Entity Framework Lazy Loading isn't working and I don't know why. It's not about not initializing Exams , because Entity Framework should do it alone when I try to access Exams property.

You didn't follow the rules to enable Entity framework to create proxies (required for lazy loading), which needs public access:

A custom data class must be declared with public access.

Make your Exam and Student public and it should work.

In c# if you don't declare access modifiers, It will accept it as internal by default.

You should declare you entity classes as public.

Secondly collections should return empty collection beside of null. So If a student doesn't have any exam, you should return empty collection. That's wyh you should change your Student Constructor also.

 public class Student
    {
        public Student()
        {
            Exams = new List<Exam>();
        }
    }

Edit: If you have ICollection or IList , ef returns empty collection. You should use this constructor, if you are using IEnumurable .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM