7-Linq查询语言
本篇博客对应视频讲解
回顾
上一期我们讲解了字符编码相关的内容,大家应该去理解字符和字节之间的关系。并学习使用Encoding类进行编码之间的转换。
今天给大家讲的内容十分的重要,也是C#等语言比其他语言更具优势的地方。它将极大的提高我们处理数据的效率,提升我们的开发体验。
何为LINQ
LINQ(Language Integrated Query)语言集成查询,允许以查询数据库相同的方式操作内存数据。 简单的说,我们有很多数据来源,数据库、文件(xml、json),内存中的数据等等。我们需要针对不同的数据类型使用不同的方法进行操作。
例如,我们处理字符串,就需要使用String类,处理列表需要使用List类中提供的方法,查询数据库更是需要特定的sql查询语言支持,非常的繁琐。而Linq就是更高层次的抽象,可应用于所有数据源的具有多种用途的语法查询特性。
这意味着,我们只需要学习一种查询方法,就可以处理各种数据了。 Linq相当的便捷和实用,正因如此,当Linq出现之后,其他语言也有相关的实现。
使用LINQ
首先给大家官方文档的地址,里面非常详细的介绍和说明了怎么使用Linq进行数据的查询和处理。 完整文档参考。 建议大家有时间就对这个文档的内容进行总体浏览,了解都包含哪些内容。之后遇到需求的时候可以有针对性的去查找 。
今天我会给出一些示例,让大家领略一下Linq的威力。
示例代码:
- 简单数组Linq操作
var numbers = new int[] { 1, 31, 22, 4, 229, 84, 8, 23 }; Console.WriteLine("原数组:"); WriteArray(numbers); // 取最大值 int max = numbers.Max(); Console.WriteLine("最大值为:" + max); // 取第三大的值 int thirdMax = numbers.OrderByDescending(m => m) .Skip(2) .First(); Console.WriteLine("第三大的数是" + thirdMax); // 取总和 int sum = numbers.Sum(); Console.WriteLine("总和为:" + sum); // 条件筛选,取所有奇数,并按从小到大排列 var result = numbers.Where(n => n % 2 == 1) .OrderBy(m => m) .ToArray(); Console.WriteLine("处理后的结果为:"); WriteArray(result);
数组输出方法
static void WriteArray(IEnumerable obj) { foreach (var item in obj) { Console.Write(item.ToString() + " "); } Console.WriteLine(); }
- 学生考试成绩查询 我们先创建学生和成绩类: Student类:Name,Class,Score Score类:English,Chinese,Math
/// <summary> /// 成绩类 /// </summary> public class Score { /// <summary> /// 数学 /// </summary> public int Math { get; set; } /// <summary> /// 英语 /// </summary> public int English { get; set; } /// <summary> /// 语文 /// </summary> public int Chinese { get; set; } } /// <summary> /// 学生类 /// </summary> class Student { /// <summary> /// 姓名 /// </summary> public string Name { get; set; } /// <summary> /// 班级 /// </summary> public string Class { get; set; } /// <summary> /// 成绩 /// </summary> public Score Score { get; set; } }
使用Linq代码示例: 先模拟我们需要数据
/// <summary> /// 初始化数据 /// </summary> /// <returns></returns> static List<Student> InitData() { string[] names = { "张三", "王五", "李四", "赵二", "丁一", "李明", "韩梅", "梦琪", "忆柳", "之桃", "慕青", "问兰", "尔岚", "元香", "初夏" }; var random = new Random(); var students = new List<Student>(); // 创建学生对象 foreach (var name in names) { var student = new Student { Name = name, Class = random.Next(1, 4) + "班" }; students.Add(student); } // 模拟学生考试成绩 foreach (var student in students) { var score = new Score { Chinese = random.Next(60, 101), English = random.Next(60, 101), Math = random.Next(60, 101) }; student.Score = score; Console.WriteLine($"{student.Class}[{student.Name}]的成绩为:" + $"数学:{score.Math};语文:{score.Chinese};英语:{score.English}" + $"总分为:{score.Math + score.Chinese + score.English}"); } return students; }
查询数据
// 初始化数据 var students = InitData(); // 找出总分最高的学生 var student = students.Select(s => { return new { Sum = s.Score.Chinese + s.Score.English + s.Score.Math, s.Name }; }).OrderByDescending(s => s.Sum) .First(); Console.WriteLine("总分最高的学生是:" + student.Name + ";总分为:" + student.Sum); // 找出平均分最高的班级 var topClass = students.GroupBy(s => s.Class) .Select(s => { return new { Average = s.Sum(m => m.Score.Chinese + m.Score.English + m.Score.Math) / s.Count(), Class = s.Key }; }) .OrderByDescending(m => m.Average); Console.WriteLine("最高班级:" + topClass.First().Class + ";平均分:" + topClass.First().Average); // 筛选出有分数小于80分的学生,按班分组 var hardStudents = students.Where(m => needImprove(m.Score)) .GroupBy(m => m.Class) .ToList(); // 输出每班内小于80分的同学 foreach (var group in hardStudents) { Console.WriteLine(group.Key + "有低于80分学生" + group.Count() + "名:"); foreach (var item in group) { Console.Write(item.Name + " "); } Console.WriteLine(); } // 内部方法,判断是否有小于80分的学科 bool needImprove(Score score) { if (score.English < 80 || score.Chinese < 80 || score.Math < 80) return true; return false; }