Reputation: 5550
I normally use the lambda notation for choice but get frustrated with joins. I set myself a simple exercise using LINQPad. The LINQ query is:
List<int> allStudents = new List<int> {1,2,3,4,5,6,7,8,9};
List <int> studentsIdList = new List<int> {1,3,5,7,9};
var q =
from c in allStudents
join p in studentsIdList on c equals p into ps
from p in ps.DefaultIfEmpty()
where p == 0
select new { Student = c};
q.Dump();
which produces the expected result set 2,4,6,8
.
HOWEVER, when I write it in lambda notation as:
List<int> allStudents = new List<int> {1,2,3,4,5,6,7,8,9};
List <int> studentsIdList = new List<int> {1,3,5,7,9};
var q =
allStudents
.GroupJoin(
studentsIdList,
m => allStudents,
n => studentsIdList,
(m, n) => new {allS = m, excS = n.DefaultIfEmpty(0)})
.Where(x => x.excS.SingleOrDefault () == 0)
.Select (x => x.allS);
q.Dump();
I get a result set of 1,2,3,4,5,6,7,8,9
AND LINQPad does not show the lambda conversion.
Two questions:
UPDATE
Using the answer below I was able to correct my attempt
List<int> allStudents = new List<int> {1,2,3,4,5,6,7,8,9};
List <int> studentsIdList = new List<int> {1,3,5,7,9};
var q = allStudents
.GroupJoin(studentsIdList,
a => a, b => b,
(a, b) => new { Id = a, Present = b.DefaultIfEmpty() })
.Where(x => x.Present.Single() == 0)
.Select(x => x.Id);
q.Dump();
Thanks very much.
Upvotes: 2
Views: 679
Reputation: 30934
The answer to your second question, is to call .AsQueryable()
on your source collection. This allows LINQPad to show C#'s translation into lambda syntax:
List<int> allStudents = new List<int> {1,2,3,4,5,6,7,8,9};
List <int> studentsIdList = new List<int> {1,3,5,7,9};
var q = from c in allStudents.AsQueryable()
join p in studentsIdList on c equals p into ps
from p in ps.DefaultIfEmpty()
where p == 0
select new { Student = c};
q.Dump();
Upvotes: 3
Reputation: 2579
This is how you write the join:
var q = allStudents
.GroupJoin(studentsIdList, a => a, b => b, (a, b) => new { Id = a, Present = b })
.Where(join => !join.Present.Any())
.Select(join => join.Id);
Of course, for this very case, using Except
would be much simpler.
Can't help with the Linqpad question as I don't use it myself.
Upvotes: 2