实体框架查找方法无法正常工作

时间:2011-04-23 13:20:37

标签: linq-to-entities code-first entity-framework-4.1

我有像这样的课程,学生和老师

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 个答案:

答案 0 :(得分:13)

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();

答案 1 :(得分:4)

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