【问题标题】:Accessing the relationship of a relationship with Entity Framework使用实体框架访问关系的关系
【发布时间】:2013-11-05 19:18:46
【问题描述】:

我是学校班级我有这个代码:

from student in this.Students where student.Teacher.Id == id select student

Student 类有两种关系:Teacher 和 School。在 School 课程中,我试图找出 Teacher 具有给定 ID 的所有学生。

问题是我得到了

System.NullReferenceException:对象引用未设置为对象的实例。

在声明中

student.Teacher.Id

我想过做this.Students.Include("Teacher"),但是this.Students没有这样的方法。任何想法如何执行该查询?

【问题讨论】:

    标签: entity-framework


    【解决方案1】:

    你显示这行代码:

    from student in this.Students where student.Teacher.Id = id select student
    

    首先,= 应该是 ==

    这只是一个错字吗?

    其次,如果您稍后不取消对教师的引用,对于以下已更正的查询,您不需要包含

    var q = from student in SomeObjectContext.Students 
            where student.Teacher.Id == id 
            select student;
    

    LINQ to Entities 不需要仅在 where 子句中包含 Inlcude。

    如果您稍后迭代结果并取消对教师的引用,您需要包含:

    foreach (var student in q)
    {
        Console.WriteLn(student.Teacher.Id);
    }
    

    第三,你显示这个错误:

    System.NullReferenceException:对象引用未设置为对象的实例。

    这不是 LINQ to Entities 错误。错误实际上是在那一行代码上,还是在其他地方?

    另外,this 是什么?如果它不是 ObjectContext,那么您很可能是 LINQ to Objects,而不是 LINQ to Entities。在这种情况下,您将无法使用 Include。如果是这样的话,那么this.Sbudents是从哪里来的呢?

    【讨论】:

    • 正如我所说,我在 School 中有该代码,所以这是 a School。目前没有可用的上下文,因此您说它是 LINQ to Objects 可能是对的。
    【解决方案2】:

    我发现调试器让我遍历查询的每次迭代:

    from student in this.Students where student.Teacher.Id == id select student
    

    所以我必须多次查看 student.Teacher.Id == id。每次我调试它都没有发生,一切都很好。我把表达式变成了:

    from student in this.Students where student.Teacher != null && student.Teacher.Id == id select student
    

    它不仅停止了崩溃,而且运行良好(所有学生都按预期选择)。我不完全确定为什么。

    【讨论】:

    • 我能猜到为什么!因为有时学生可能有老师,有时没有。学生必须教吗?!如果你声称它有时会返回结果,那就意味着它是真的,有时学生没有老师。
    • mosessaur,好主意;不幸的是,教师是一个不可为空的字段。但是既然正如其他人所说,这不再是LINQ-to-Entities,而是LINQ-to-Objects,也许你是对的。另外,如果由于某种原因有一些学生的老师是空的,当我改变所有这些学生的学校时,那些应该被留下,而他们没有。非常令人费解。
    • 小心。这可能是巧合地“起作用”。可能是老师为空的学生碰巧不在您要加载的课程中。但你不能指望这一点。您需要首先解决为什么没有加载教师的问题,这可以追溯到您的 LINQ to Entities 查询。
    • 据我所知,无论是在调试时还是在运行时,都会为所有学生加载教师。更有可能是我得到额外的 Student 对象没有正确初始化,但由于我在调试时不会发生这种情况,所以很难找出问题所在。
    【解决方案3】:

    Include 子句可用于 linq 到实体查询。例如:

    using (YourDataContext db = new YourDataContext())
            {
                var query = from s in db.Students.Include("Teacher")
                            where s.Teacher.ID == 1
                            select s;
                 //etc...
            }
    

    我猜 this.Students 是已经被拉入内存的集合,因此您可以在从 dbs 检索学生的部分中考虑此代码。如果您想稍后加载学生的教师(非常重要的是学生实体由 ObjectContext 跟踪!)您可以在 TeacherReference 属性上使用 Load 方法,但对于 this.Students 集合中的每个学生分别:

    student.TeacherReference.Load();
    

    希望对你有帮助

    【讨论】:

    • 如果对 Teacher.Id 的唯一引用是 LINQ to Entities 查询的 where 子句,则不需要包含。仅当您在迭代结果时检查 Teacher.* 时才需要包含。
    • 是的,包含不能用于对象的关系。我无法再访问数据库,因为我在 School 班级内。我可以很好地加载引用,但是迭代引用的所有元素以引导其中一个引用听起来不太好,而且会相当浪费。
    猜你喜欢
    • 2017-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多