Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF6 does not lazy load navigation property

I'm having an issue with EF6 lazy loading. I've searched StackOverflow, but the other questions I've found doesn't fit my case.

I'm using the virtual keyword and my classes are public. LazyLoadingEnabled and ProxyCreationEnabled are both set to true.

When I load a course object from the db, presentationId is set to the correct id and presentation is null which is correct, because it hasn't been loaded yet.

When I pass the presentation property to the PresentationsController.ToDto() method it should be lazy loaded, but I get a null reference exception inside the method because it's still null.

I know that the relationships are working because when I force load the presentation property of a course in the Watch window with a break point at the public static CourseDto ToDto(Course item, DnbContext db) method it gets loaded. See images:

As you can see item.presentation is null:

enter image description here

When I manually evaluate db.courses.Find(257).presentation which is referencing the same presentation as the item object does, they're both loaded:

enter image description here

Here are my POCOs:

public abstract class BaseModel : ISoftDelete {
    public int id { get; set; }
}

public class Course : BaseModel {
    [Required]
    public int presentationId { get; set; }
    public virtual Presentation presentation { get; set; }
}

My Web API controller methods:

// GET api/Courses/5
public CourseDto GetCourse(int id) {
    var item = db.courses.FirstOrDefault(x => x.id == id);
    return ToDto(item, db);
}

public static CourseDto ToDto(Course item, DnbContext db) {
    var dto = new CourseDto();

    if (item.presentationId > 0) dto.presentation = PresentationsController.ToDto(item.presentation, db);

    return dto;
}

Any ideas?

like image 252
Hein Andre Grønnestad Avatar asked Mar 21 '23 08:03

Hein Andre Grønnestad


1 Answers

Entities must have explicitly declared public constructors if you want to use lazy loading via dynamic proxies. (If you have other with parameters)

public abstract class BaseModel : ISoftDelete {
    public BaseModel() { }
    public int id { get; set; }
}

public class Course : BaseModel {
    public Course() { }
    [Required]
    public int presentationId { get; set; }
    public virtual Presentation presentation { get; set; }
}
like image 183
Mario Avatar answered Apr 26 '23 11:04

Mario