前言
学习了数组的查询之后。前面就知道了Linq数据源必须是是可枚举的——即必须是数组和集合以便从中选择一个。所以接下学习的就是集合了。集合里面最常见的就是对象了,那么我们就针对对象查询,也是项目中很常用的。
正文
1.查询的是对象
那么首先建立对象,再对其进行查询
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5: using System.Threading.Tasks;
6: using System.IO;
7:
8: namespace ConsoleApplication1
9: {
10: class LinqTest2
11: {
12: static void Main(string[] args)
13: {
14: List<Student> students = new List<Student> {
15: new Student{Id=123,Name="李山",Info="学习成绩一般",Grade="1年级"},
16: new Student{Id=123,Name="李四",Info="学习成绩良好",Grade="2年级"},
17: new Student{Id=12345,Name="李五",Info="学习成绩一般",Grade="3年级"},
18: new Student{Id=12346,Name="李六",Info="学习成绩优秀",Grade="6年级"},
19: new Student{Id=12789,Name="李七",Info="学习成绩优秀",Grade="5年级"},
20:
21: };
22: /////////////////////////////////////////////////////////
23: //第一种原始的查询方法。很像sql查询语句,只不过这里用的是对象
24: var queryResults= from c in students
25: where c.Id==123
26: select c //此处是查询整个对象
27: ;
28: foreach(Student s in queryResults)
29: {
30: Console.WriteLine(s);//这里输出的是c默认调用其ToString()的方法,不复写这输出类名
31: //Console.WriteLine("Student{0}:{1},{2}",s.Id,s.Name,s.Info);
32: }
33: /////////////////////////////////////////////////////////
34: Console.ReadKey();
35: }
36: }
37: class Student
38: {
39:
40: public int Id { get; set; }
41: public string Name { get; set; }
42: public string Info { get; set; }
43: public string Grade { get; set; }
44:
45: public override string ToString()
46: {
47:
48: return "ID:" + Id + "Name:" + Name + "Info" + Info + "Grade" + Grade;
49: }
50:
51: }
52: }
结果:
ID:123Name:李山Info学习成绩一般Grade1年级
ID:123Name:李四Info学习成绩良好Grade2年级
2 查询的是对象中某个属性或者是表达式
1: ///////////////////////////////////////////////////////////////
2: var queryResults= from c in students
3: select c.Id+1 //表达式
4: //select c.Id //查对象的Id
5: //select c.Name.ToUpper() //对对象中得Name属性进行操作
6: ;
7: foreach (int s in queryResults)//相应的这里也要做类型转变
8: {
9: Console.WriteLine(s);
10: }
11: ///////////////////////////////////////////////////////////////
12: Console.ReadKey();
结果:
124
124
12346
12347
12790
3 查询的时多字段,多属性需要投影——在查询中创建新的对象
1: ///////////////////////////////////////////////////////////////
2: //方法一查询方法:
3: //var queryResults = from c in students
4: // where c.Id==123
5: // select new { c.Id, c.Name } //多字段查询
6: // ;
7: //方法二方法语法:
8: var queryResults = students.Where(c => c.Id == 123).Select(c=>new {c.Id,c.Name });
9: foreach (var s in queryResults)//此处的对象类型 变为var
10: {
11: Console.WriteLine(s);
12: }
13: ///////////////////////////////////////////////////////////////
14: Console.ReadKey();
结果:
{ Id = 123, Name = 李山 }
{ Id = 123, Name = 李四 }
说明:
1.students.Where(c => c.Id == 123).Select(c=>new {c.Id,c.Name });对于where条件和select方法可以互换,但是是从左到右执行的。也就是说先在where的条件下所得的结果集后在执行select方法在得到结果;
2.但是发现Select(c=>new {c.Id+1,c.Name });其中c.Id+1是不可行的,必须要新建新的列才可以,如下:
1: var queryResults = students.Where(c => c.Id == 123)
2: .Select(c => new {ID=c.Id+1,c.Name,nameInfo=c.Name+c.Info });
结果:
{ ID = 124, Name = 李山, nameInfo = 李山学习成绩一般 }
{ ID = 124, Name = 李四, nameInfo = 李四学习成绩良好 }
4 其他方法
1.Distinct() 去除完全相同的列
使用:
var queryResults = students.Where(c => c.Id == 123).Select(c=>new {c.Id, c.Name }).Distinct();
或者
var queryResults = (from c in students where c.Id == 123 select new { c.Id, c.Name }).Distinct();
2. Any()和All() 两个布尔方法,快速确定数据的某个条件是否为true或者false
1: bool allId = students.All(c => c.Id == 123);//students中的全部的Id是否都为123,是返回true,否则false
2: bool anyId = students.Any(c => c.Id == 123);//students中的某些Id是否为123,是返回true,否则false
3: Console.WriteLine(allId);
4: Console.WriteLine(anyId);
5: Console.ReadKey();
结果:
False
True
3.ThenBy() 多级排序方法
1: var queryResults = students.Select(c => c)
2: .OrderByDescending(c=>c.Id)//首次排序以Id为降序
3: .ThenByDescending(c=>c.Name)//次之以Name降序
4: .ThenBy(c=>c.Info);//在此之以Info升序
5: foreach (var s in queryResults)//此处的对象类型可为var,也可为Student,方便起见使用var
6: {
7: Console.WriteLine(s);
8: }
结果:
ID:12789Name:李七Info学习成绩优秀Grade5年级
ID:12346Name:李六Info学习成绩优秀Grade6年级
ID:12345Name:李五Info学习成绩一般Grade3年级
ID:123Name:李四Info学习成绩良好Grade2年级
ID:123Name:李山Info学习成绩一般Grade1年级
4.Take(n) 提取结果集中前n个数据
Skip(n) 提取结果集中除去前n个数据后剩下的数据
使用:(注意是对结果集操作)
queryResults.Take(5);
queryResults.Skip(5);
5.First() 返回结果集中第一个匹配给定条件的元素,没有这报异常
FirstOrDefault() 与上面一样,只是没有的时候返回Null
使用:(注意返回的是一个对象啊)
var queryResults = students.First(c => c.Id == 123);
var queryResults = students.FirstOrDefault(c => c.Id == 123);
4 组合查询 OrderBy
为演示效果,重写代码,代码如下
创建新的类
1: class ClassRoom
2: {
3:
4: public int Id { get; set; }
5: public string Name { get; set; }
6: public int StuId { get; set; }
7: public int Math { get; set; }
8: public int English { get; set; }
9:
10: }
Main方法中:
1: List<ClassRoom> students = new List<ClassRoom> {
2: new ClassRoom{Id=1,StuId=123,Name="李三",Math=85,English=69},
3: new ClassRoom{Id=1,StuId=125,Name="李四",Math=82,English=99},
4: new ClassRoom{Id=1,StuId=124,Name="李五",Math=81,English=82},
5: new ClassRoom{Id=2,StuId=126,Name="李流",Math=88,English=85},
6: new ClassRoom{Id=2,StuId=127,Name="李气",Math=95,English=81},
7: new ClassRoom{Id=2,StuId=128,Name="李八",Math=65,English=88},
8: new ClassRoom{Id=2,StuId=129,Name="李一",Math=75,English=83},
9: };
10: ////////////////////////////////////////////////////////////////
11: var queryResults = from c in students
12: group c by c.Id into classroom //产生一个新的结果集classroom方便做运算
13: select new { classid = classroom.Key, totleManth = classroom.Sum(c => c.Math), totleEnglish = classroom.Sum(c => c.English) };
14: foreach (var s in queryResults)//此处的对象类型可为var,也可为Student,方便起见使用var
15: {
16: Console.WriteLine(s);
17: }
18: ////////////////////////////////////////////////////////////////////////
19: Console.ReadKey();
结果:
{ classid = 1, totleManth = 248, totleEnglish = 250 }
{ classid = 2, totleManth = 323, totleEnglish = 337 }
注解:
1、select new { classid = classroom.Key,//这里的Key指的就是 group c by 后面的c.Id
totleManth = classroom.Sum(c => c.Math), //使用新的结果集做
totleEnglish = classroom.Sum(c => c.English) };
附注:
OK关于集合的中得对象的LinQ就到这里吧!