Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework Find method not working properly

I have classes called Course, Student and Teacher like this

public class Course
    {
        [Key, DatabaseGenerated(DatabaseGenerationOption.Identity)]
        public Guid CourseId { set; get; }
        public ICollection<Student> Students { set; get; }
        public Teacher Teacher { get; set; }      

    }



public class Student
    {
        [Key, DatabaseGenerated(DatabaseGenerationOption.Identity)]
        public Guid StudentId { set; get; } 
        public ICollection<Course> Courses { set; get; }
    }




public class Teacher
    {
        [Key, DatabaseGenerated(DatabaseGenerationOption.Identity)]
        public Guid TeacherId { get; set; }
        public ICollection<Course> Courses { get; set; }
    }

I am trying to Get a course by primary key as follow

Course c = _unitOfWork.DbContext.Set<Course>().Find(keyValue);

i get the course object from the database but the Students and Teacher property of the course are null

Am i missing Something?? Thanks

like image 958
taher chhabrawala Avatar asked Dec 04 '22 08:12

taher chhabrawala


1 Answers

Find works correctly because EF never loads related entities itself. To load related properties you must either use eager or lazy loading. The third option is sometimes refered as explicit loading.

Lazy loading will provide you automatic loading of related entities but it will generate additional queries to the database. Related entity or related collection will be loaded when you access the property for the first time. To use lazy loading you must mark all navigation properties in the entity as virtual (@ckal provided you an example). Also lazy loading works only if context used to load the main entity is still alive.

Eager loading will define which relation must be load together with your main entity. Eager loading is executed by Include method. You can rewrite Find as:

Course c = _unitOfWork.DbContext
                      .Set<Course>()
                      .Include(c => c.Students)
                      .Include(c => c.Teacher)
                      .SingleOrDefault(c => c.CourseId == keyValue);

Explicit loading will allow you to explicitly say that some relation should be loaded. You can even define some condition for loading related entities which is not possible with other two methods. You must first load the main entity and before disposing the context you can do something like:

context.Entry(course).Collection(c => c.Students).Load();
like image 144
Ladislav Mrnka Avatar answered Dec 24 '22 13:12

Ladislav Mrnka