Entity Framework Find метод не работает должным образом - PullRequest
4 голосов
/ 23 апреля 2011

У меня есть классы под названием Курс, Студент и Учитель, подобные этому

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; }
    }

Я пытаюсь получить курс по первичному ключу следующим образом

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

я получаю объект курса из базы данных, но свойство «Студенты и учителя» равно нулю

Что-то мне не хватает ?? Спасибо

Ответы [ 2 ]

13 голосов
/ 23 апреля 2011

Find работает правильно, потому что EF никогда не загружает связанные сущности самостоятельно.Чтобы загрузить связанные свойства, вы должны использовать либо нетерпеливую, либо ленивую загрузку.Третий вариант иногда называют явной загрузкой.

Ленивая загрузка обеспечит вам автоматическую загрузку связанных сущностей, но сгенерирует дополнительные запросы к базе данных.Связанная сущность или связанная коллекция будут загружены при первом обращении к свойству.Чтобы использовать отложенную загрузку, вы должны пометить все свойства навигации в сущности как virtual (@ckal предоставил вам пример).Кроме того, отложенная загрузка работает, только если контекст, используемый для загрузки основного объекта, все еще активен.

Стремительная загрузка определит, какое отношение должно быть загружено вместе с вашим основным объектом.Стремительная загрузка выполняется методом Include.Вы можете переписать Find как:

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

Явная загрузка позволит вам явно сказать, что какое-то отношение должно быть загружено.Вы даже можете определить некоторые условия для загрузки связанных сущностей, что невозможно с двумя другими методами.Сначала вы должны загрузить основную сущность, а перед удалением контекста вы можете сделать что-то вроде:

context.Entry(course).Collection(c => c.Students).Load();
4 голосов
/ 23 апреля 2011

Добавьте virtual в свойства навигации, чтобы включить отложенную загрузку.

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