我通常使用 lambda 表示法进行选择,但对连接感到沮丧。我使用 LINQPad 给自己设置了一个简单的练习。LINQ 查询为:
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();
生成预期的结果集2,4,6,8
。
但是,当我用 lambda 表示法将其编写为:
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();
我得到一个结果集1,2,3,4,5,6,7,8,9
LINQPad 不显示 lambda 转换。
两个问题:
- 我的 lambda 查询有什么问题?
- 如何让 LINQPad 显示 lambda 翻译?
更新
使用下面的答案,我能够纠正我的尝试
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();
非常感谢。
第二个问题的答案是调用源集合上的.AsQueryable()
。这允许 LINQPad 显示 C# 对 lambda 语法的转换:
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();
这是你编写连接的方式:
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);
当然,在这种情况下,使用Except
会简单得多。
无法帮助解决Linqpad问题,因为我自己不使用它。