tags:

views:

132

answers:

3

I've looked at the 101 Linq Samples here but I can't see anything like this in that list. If I'm just not seeing a relevant example there, please link to it.

If I have these 3 classes:

class Student { int id; string name }
class Course { int id, string name }
class Enrolment { int studentId; int courseId; }

How would I use LINQ to get a list of courses a student is enrolled on? (assume I have an IList of all three classes)

+9  A: 

How about:

IEnumerable<Course> FindCoursesForStudent(Student student)
{
    return from enrolment in Enrolments 
           where enrolment.studentId == student.id
           join course in Courses
              on enrolment.courseId equals course.id
           select course;
}
Jon Skeet
Skeeted AGAIN by mere seconds!
Adam Robinson
Damn, 1 minute in it!
Marc Gravell
A: 
var courses = (from course in courseList 
    join enr in enrolmentList on enr.courseId equals course.id 
    where enr.studentId = <student id variable> 
    select course);
Adam Robinson
It's more efficient to do the where *before* the join - there's no sense in matching a load of enrolments with courses in the join, only to throw them away again immediately.
Jon Skeet
Sounds like LINQ needs a better optimizer, then ;)
Adam Robinson
+1  A: 

Not an explicit answer, but perhaps implicitly helpful building your system.

Have you considered a richer domain model like so:

class Student { int id; string name; IEnumerable<Enrolment> enrolments }
class Course { int id, string name; }
class Enrolment { Student student; Course course; }

?

The Student class could then have a method GetEnroledCourses() like so:

public IEnumerable<Course> GetEnroledCourses()
{
   return enrolements.Select(enrolement => enrolement.Course).ToList().AsReadonly();
}

A model that's merely a one-to-one mapping to the database suffice in some contexts, but if you have complex business logic such an «anemic domain model» might bite you.

Martin R-L