using System.Collections.Generic;
public static void Main()
var students = new List<Student> {
new Student { id=1, name="john"},
new Student { id=2, name="mike"},
new Student { id=3, name="josh"},
var classes = new List<Class> {
new Class { id=1, name="geography"},
new Class { id=2, name="math"},
new Class { id=3, name="history"},
new Class { id=4, name="biology"}
var studentClasses = new List<StudentClass> {
new StudentClass { id=1, classId=1, studentId=1 },
new StudentClass { id=2, classId=2, studentId=2 },
new StudentClass { id=3, classId=2, studentId=3 }
join ljsc in studentClasses
on c.id equals ljsc.classId
into leftjoinStudentClasses
from sc in leftjoinStudentClasses.DefaultIfEmpty(new StudentClass())
on sc.studentId equals ljs.id
from s in leftjoinStudents.DefaultIfEmpty(new Student())
group new { s,c } by c.name into grp
classname = grp.Key, students = from ss in grp select ss.s.name
foreach (var item in query)
var studentList = item.students.Any( s => !string.IsNullOrEmpty(s) ) ? string.Join(",", item.students) : "null";
Console.WriteLine("{0}: {1}", item.classname, studentList);
public int id { get; set; }
public string name { get; set; }
public int id { get; set; }
public string name { get; set; }
public class StudentClass
public int id { get; set; }
public int studentId { get; set;}
public int classId {get;set;}