测试的数据:
//学生列表
List<Student> slist = new List<Student>();
slist.Add(new Student() { Id=1,Name="学生零",Course="语文"});
slist.Add(new Student() { Id = 2, Name = "学生一", Course = "数学" });
slist.Add(new Student() { Id = 3, Name = "学生一", Course = "语文" });
slist.Add(new Student() { Id = 4, Name = "学生零", Course = "数学" });
slist.Add(new Student() { Id = 5, Name = "学生四", Course = "语文" });
slist.Add(new Student() { Id = 6, Name = "学生五", Course = "化学" });
slist.Add(new Student() { Id = 7, Name = "学生六", Course = "语文" });
slist.Add(new Student() { Id = 8, Name = "学生七", Course = "生物" });
slist.Add(new Student() { Id = 9, Name = "学生零", Course = "历史" });
slist.Add(new Student() { Id = 10, Name = "学生九", Course = "物理" });
slist.Add(new Student() { Id = 11, Name = "学生零", Course = "生物" });
//课目列表
List<Course> clist = new List<Course>();
clist.Add(new Course() {Id=0,Name="语文",Level=3 });
clist.Add(new Course() { Id = 1, Name = "数学", Level = 5 });
clist.Add(new Course() { Id = 2, Name = "物理", Level = 6 });
clist.Add(new Course() { Id = 3, Name = "化学", Level = 4 });
clist.Add(new Course() { Id = 4, Name = "历史", Level = 3 });
clist.Add(new Course() { Id = 5, Name = "生物", Level = 1 });
两个集合的联接查询:
Linq方式一:直接联接
//两个集合的连接查询
var result = from s in slist //第一个集合
from c in clist //第二个集合
where s.Course == c.Name && c.Level > 5 //联接条件
select new { s = s, c = c }; //新的集合结构
Linq方式二:使用Join ... On....联接
//使用Join on 实现两个集合的连接查询,要使用equals让两个集合的关联属性相等
var result = from s in slist //第一个集合
join c in clist on s.Course equals c.Name //第二个集合及联接条件,使用equals
where s.Id == 1
select new { s = s, c = c }; //新的集合结构
Lambda表达式 方式一:SelectMany方法
//使用Lambda表达式实现两个集合的连接查询
//与上述的Linq结果一致,
//参数1:第一个委托或匿名方法返回要连接的目标集合
//参数2:第二个委托或匿名方返回当前集合与目标集合组成的一个新的集合
//where用来限定新的集合中的条件
var result = slist.SelectMany(s => clist, (s, c) => new { s=s,c=c}).Where(p=>p.s.Course==p.c.Name&&p.c.Level>5);
Lambda表达式 方式二:Join方法
//使用Lambda表达式实现两个集合的连接查询
//参数1:要联接的第二个集合
//参数2:源集合(即当前的主集合对象,也就是第一个集合)要与第二个集合联接的字段
//参数3:第二个集合与第一个集合联接的字段
//参数4:返回新的结果集结构组成
var result = slist.Join(clist, s => s.Course, c => c.Name, (s, c) => new { s = s,c=c });//.Where(p=>p.c.Name==p.s.Course);
两个集合的联接查询分组:
Linq方式一:使用主集合的默认字段作为分组依据
//分组Group,两个集合联接
var result = from c in clist //第一个集合,主集合
join s in slist on c.Name equals s.Course //使用Join...On的方式联接第二个集合,使用equals
into groups //使用默认的属性c.Name分组
orderby groups.Count() //排序
select new { c = c,count = groups.Count(), }; //groups.Key的内容指的是分组的那个属性c.Name
Linq方式二:使用主集合指定的字段作为依据
//分组Group,两个集合联接
var result = from c in clist //第一个集合,主集合
join s in slist on c.Name equals s.Course //使用Join...On的方式联接第二个集合,使用equals
group c by c.Name into groups //按指定的属性分组
select new { c = groups.First(), count = groups.Count() }; //groups.Key的内容指的是分组的那个属性c.Name
Lambda表达式 方式一:SelectMany+GroupBy方法
//Lambda表达式分组的两个集合联接,SelectMany+GroupBy方法
//SelectMany为联接查询,产生新结果集
//GroupBy分组方法,参数:指定集合中哪个字段作为分组依据
var result=slist.SelectMany(s=>clist,(s,c)=>new {s=s,c=c}).Where(p=>p.s.Course==p.c.Name).GroupBy(p=>p.c.Name);
Lambda表达式 方式二:GroupJoin方法
//GroupJoin方法实现集合联接查询的分组
//参数1:要联接的第二个集合
//参数2:源集合(即当前集合,也就是第一个集合)与第二个集合联接的字段
//参数3:第二个集合与第一个集合联接的字段
//参数4:返回的新集合的结构
var result = clist.GroupJoin(slist, c => c.Name, s => s.Course, (c, s) => new { c = c, count = s.Count() });
//输出
foreach (var item in result)
Console.WriteLine(item+":"+item.count);
从Linq分组的结果中再次查询:
var query = from book in books
//where book.pubYear.StartsWith("18") //限定条件
// where book.authors.Any(p=>p.country.StartsWith("C")) //限定条件
//orderby book.pubYear, book.id descending //默认ascending升序,descending降序
group book by book.name into groups //结果保存在Groups中
from item in groups //从分组中再次查询
select item;
在Linq中定义变量的用法:
var query = from file in System.IO.Directory.GetFiles("c:/")
//select file ; //输出所有文件的完整路径,包括文件名
let fileInfo = new System.IO.FileInfo(file) //使用let关键字在linq中定义变量
select new { fileInfo.Name,fileInfo.Length,fileInfo.LastWriteTime}; //使用定义的变量