Entity Framework 6 延迟加载不起作用。

3
我创建了两个模型类:StudentExam。 < p > 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; } 
}

考试:
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; }
}

但是似乎懒加载不起作用,这里是我检索数据的示例:
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();
}

我尝试访问students.Exams属性时,出现了NullReferenceException异常。我的代码哪里有问题?
我的代码问题在于Entity Framework的延迟加载未能正常工作,我不知道为什么。这与未初始化Exams无关,因为当我尝试访问Exams属性时,Entity Framework应该自动进行初始化。

@Nasreddine,不是很对。我已经阅读了EF在Lazy Loading期间应该注意集合是否已初始化并进行初始化的内容。我在构造函数中添加了初始化,但是Lazy Loading仍然无法正常工作。现在当我尝试循环遍历学生考试(这些考试存在于数据库中)时,我没有得到任何输出。student.Exams是一个空集合,但是EF应该已经加载它了。 - monoh_
@TomTom,@Rene Vogt,我的问题怎么会是如何修复NRE的重复?我的问题是EF延迟加载不起作用,而不是“Exams”为空,因为EF应该自己初始化此集合。 - monoh_
@AlexanderDerck,在构造函数中初始化集合可以防止出现“NullReferenceException”,但是即使在数据库中有给定学生ID的考试,集合仍然为空。我已经阅读了许多类似的问题,但仍然无法使我的代码工作。 - monoh_
2个回答

13

您没有按照规定启用实体框架创建代理(需要进行延迟加载),这需要公共访问权限:

自定义数据类必须声明为公共访问。

将您的考试 (Exam)学生 (Student)设为公共,它就可以正常工作了。


3
愿上帝(或飞行意大利面怪物)保佑你。 - arminb

2

在c#中,如果你没有声明访问修饰符,它会默认为internal。

你应该将实体类声明为public。

其次,集合应该返回空集合而不是null。所以如果一个学生没有任何考试,你应该返回空集合。这就是为什么你应该改变你的Student构造函数。

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

编辑: 如果您有ICollectionIList,EF将返回空集合。如果您使用IEnumurable,则应使用此构造函数。


3
经过测试,即使没有构造函数或延迟初始化集合,您也会得到一个空集合。我认为这只是在旧版本的 EF 中需要。 - Alexander Derck
我不知道那个。谢谢你提供的信息。 - Erkan Demirel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接