views:

98

answers:

3

I the School class I have this code:

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

The Student class there are two relationships: Teacher and School. In the School class I'm trying to find out all the students whose Teacher has a given id.

The problem is that I get

System.NullReferenceException: Object reference not set to an instance of an object.

in the statement

student.Teacher.Id

I thought of doing this.Students.Include("Teacher"), but this.Students doesn't have such a method. Any ideas how can I perform that query?

A: 

The Include clause can be used in linq to entities query. For example:

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

I guess that this.Students is collection pulled into memory already, so you might consider this code in the part you are retrieving students from dbs. If you want to load Teacher of the Student later on ( very importand is that student entities are tracked by ObjectContext!) you can use the Load mehtod on TeacherReference property, but for every student in this.Students collection separately:

student.TeacherReference.Load();

Hope this helps

Misha N.
Include isn't necessary if the only reference to Teacher.Id is the where clause of a LINQ to Entities query. Include is only necessary if you examine Teacher.* when iterating the results.
Craig Stuntz
Yes, Include can't be used in a relationship of an object. I don't longer have access to the db, as I am inside the School class. I can load a reference just fine, but iterating over all elements of a reference to lead one of their references doesn't sound fine and it's going to be rather wasteful.
J. Pablo Fernández
A: 

You show this line of code:

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

First, the = should be a ==

Is that just a typo?

Second, you don't need Include for the following, corrected query, if you don't dereference Teacher later on:

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

LINQ to Entities doesn't require Inlcude for just the where clause.

You would need Include if you later iterated the results and dereferenced Teacher:

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

Third, you show this error:

System.NullReferenceException: Object reference not set to an instance of an object.

This is not a LINQ to Entities error. Is the error actually on that line of code, or is it somewhere else?

Also, what's this? If it's not an ObjectContext, then you are in likely LINQ to Objects, not LINQ to Entities. In that case, you wouldn't have Include available. If this is the case, then where does this.Sbudents come from?

Craig Stuntz
As I said, I have that code inside School, so this is *a* School. No context is available at this moment so you are probably right in saying it's LINQ to Objects.
J. Pablo Fernández
OK, if you're in LINQ to objects then you must either Load (though that does require School to be attached to a live context) or add the Include to whatever populated school originally.
Craig Stuntz
A: 

I've found the debugger let me walk throu each iteration of the query:

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

so I've got to see student.Teacher.Id == id many times. Every time I was debugging it didn't happen and everything worked just fine. I turned the expression into:

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

and it not only stopped crashing, but it worked fine as well (all students where selected as expected). I'm not totally sure why.

J. Pablo Fernández
I can guess why! because sometimes a Student might have a teacher an sometimes not. Does a teach mandatory for a student?!And if you claim that it sometimes returns results then that means it is true, sometimes a student doesn't has a teacher.
mosessaur
mosessaur, good idea; unfortunately, Teacher is a non-nullable field. But since as others said, this is no longer LINQ-to-Entities, but LINQ-to-Objects, maybe you are right. Also if for some reason there were some students with null teacher, when I changed the school of all those students, those should be left behind, and they are not. Very puzzling.
J. Pablo Fernández
Be careful. This may "work" by coincidence. It could be that the students where the teacher is null don't happen to be in the class you're trying to load. But you can't count on that. You need to solve the problem of why the teachers aren't being loaded in the first place, which goes back to your LINQ to Entities query.
Craig Stuntz
The teachers are loaded for all students as far as I can tell, either at debug-time or at run-time. It's more likely that I'm getting extra Student objects not properly initialized, but since that doesn't happen when I'm debugging, it's hard to find out the problem.
J. Pablo Fernández