I would like to understand how to join two lists using 'contains' instead 'equals'. There are similar questions here on SO, but nothing seems to work. Here is my sample code, my aim is to get the student who does not belong to any classRoom:
var a = new Student("A");
var b = new Student("B");
var c = new Student("C");
var d = new Student("D");
var e = new Student("E");
var f = new Student("F");
var students = new List<Student>() { a, b, c, d, e, f };
var classRoomA = new ClassRoom();
classRoomA.Students.Add(a);
classRoomA.Students.Add(b);
var classRoomB = new ClassRoom();
classRoomB.Students.Add(c);
classRoomB.Students.Add(d);
var classRoomC = new ClassRoom();
classRoomC.Students.Add(e);
var classes = new List<ClassRoom> { classRoomA, classRoomB, classRoomC };
//option A. This works
var studentsWithoutClassRoom = students
.Where(stu => !classes.Any(r => r.Students.Contains(stu)))
.Select(s => s);
//optionB .This in one of many options that
//I have tried and it gives very interesting results
var studentsWithoutClassRoomTest = from w in students
from l in classes
where !l.Students.Contains(w)
select l;
As you can see I can get the answer using optionA, but I would like to understand is it possible to get it done using approach in optionB?
Try the following query:
var studentsWithoutClassRoomTest =
from w in students
join s in classes.SelectMany(c => c.Students) on w equals s into gj
from s in gj.DefaultIfEmpty()
where s == null
select w;