C# Linq 作者:马育民 • 2025-03-22 22:35 • 阅读:10007 # 介绍 Linq(Language Integrated Query),语言集成查询,是一种使用 **类似SQL语句** 操作多种数据源的功能。 从.net framework3.5中开始引入,能够提升程序数据处理能力和开发效率,具有集成性、统一性、可扩展性、抽象性、说明式编程、可组成型、可转换性等优势。 ### 支持的数据源 包括但不限于: - **内存中的集合**(如 `List`,`Array`,`SortedSet`,`Stack`,`Queue` 等) - 数据库(如SQL Server) - XML文档 - Web服务 ### 类比 Java 的 stream 类似 Java 的 stream,但功能更强大 ### 实现方式 有两种: - 类似 SQL 语句(某些功能不支持,需要方法查询) - 方法查询。类似 Java 的 stream,通过集合的 **扩展方法** 和 **lambda表达式** 实现 **原理:** 标准查询运算符是一组 **扩展方法**,它们提供了一种 **函数式** 的方式来构建查询。这些方法定义在 `System.Linq.Enumerable` 类中,适用于所有实现了 `IEnumerable` 接口的集合。 # 类 SQL 语句实现方式 常见的标准查询运算符包括: - Where:过滤集合中的元素。 - Select:投影每个元素。 - OrderBy 和 OrderByDescending:按升序或降序排序。 - GroupBy:根据键值对元素进行分组。 - Join:将两个集合基于键值进行关联。 - Any 和 All:检查集合是否满足某些条件。 - Count 和 Sum:计算集合的大小或求和。 ## 整体语法 ``` from source in collection:指定查询的数据源。 where condition:指定筛选条件。 orderby key [descending]:指定排序条件。 select result:定义查询结果,一般以 select 结尾 ``` ## 基本查询 #### 语法 ``` from item in collection:指定查询的数据源 select item:定义查询结果 ``` **理解:** `from item in collection` 类似 `foreach( var item in collection )` #### 例子 ``` var nums = new int[] { 56, 97, 98, 57, 74, 86, 31, 90 }; //num为数据中的每个元素(相当于foreach中迭代变量) var queryInfo = from num in nums select num; foreach (var item in queryInfo) { System.Diagnostics.Debug.WriteLine(item); } ``` 执行结果: ``` 97 98 74 86 90 ``` ## where条件查询 where子句用来指定筛选的条件 #### 语法 ``` from item in collection:指定查询的数据源。 where condition:指定筛选条件。 select item:定义查询结果 ``` #### 例子 ``` var nums = new int[] { 56, 97, 98, 57, 74, 86, 31, 90 }; //num为数据中的每个元素(相当于foreach中迭代变量) var queryInfo = from num in nums where num >60 select num; foreach (var item in queryInfo) { System.Diagnostics.Debug.WriteLine(item); } ``` 执行结果: ``` 97 98 74 86 90 ``` ## select查询列 select子句,基于查询结果返回需要的 字段,并能够对返回值指定类型。对任意想要获取到返回结果的linq语句,必须以 `select` 或 `group` 结束。 准备工作: ``` class Person { public string Name { set; get; } public int Age { set; get; } public string Gender { set; get; } public override string ToString() => Name; } ``` 初始化 `List`: ``` static List init() { List personList = new List { new Person { Name = "李雷", Age = 18, Gender = "Male" }, new Person { Name = "张三", Age = 19, Gender = "Male", }, new Person { Name = "韩梅梅", Age = 17,Gender = "Female", } }; return personList; } ``` #### 查询一列 ``` List list = init(); // 当 item 是对象时,可以只查询某个属性 var queryInfo = from item in list select item.Name; foreach (var item in queryInfo) { Console.WriteLine(item); } ``` 执行结果: ``` 李雷 张三 韩梅梅 ``` #### 查询整个对象 ``` List list = init(); // 当 item 是对象时,也可以查询 item var queryInfo = from item in list select item; foreach (var item in queryInfo) { Console.WriteLine(item.Name+","+item.Age); } ``` 执行结果: ``` 李雷,18 张三,19 韩梅梅,17 ``` #### 查询多列 ``` List list = init(); // Select 后面跟匿名类,封装查询的字段 var queryInfo = from item in list select new { username = item.Name, uesrAge = item.Age }; foreach (var item in queryInfo) { Console.WriteLine(item.username + ","+item.uesrAge); } ``` 执行结果: ``` 李雷,18 张三,19 韩梅梅,17 ``` ## order by linq中语句默认展示为升序,降序使用 `descending` #### 语法 ``` from item in collection:指定查询的数据源。 where condition:指定筛选条件。 orderby key [descending]:指定排序条件。 select 字段:定义查询结果,一般以 select 结尾 ``` #### 例子-升序 ``` var scores = new int[] { 56, 97, 98, 57, 74, 86, 31, 90 }; var query = from item in scores orderby item select item;//升序 foreach (var item in query) { Console.WriteLine(item); } ``` #### 例子-降序 ``` //var orderQuery = from item in scores orderby item descending select item;//降序 ``` ## group by `group by` 子句用来对查询结果进行分组 - 如果结果分为两组,且 **未指定key** 的情况下,`key` 取值默认是 `true` 和 `false`。 - 如果分为多组,获取数据结果时需要手动遍历 `key` 获取对应的 `value` #### 语法 ``` from item in collection:指定查询的数据源。 group item by item.属性 ``` #### 例子 ``` List list = init(); // Select 后面跟匿名类,封装查询的字段 var queryInfo = from item in list group item by item.Gender; foreach (var item in queryInfo) { Console.WriteLine(item.Key); } ``` ## group by 聚合查询 #### 例子 ``` List list = init(); // Select 后面跟匿名类,封装查询的字段 var queryInfo = from item in list group item by item.Gender into g select new { Key = g.Key, count = g.Count(), maxAge = g.Max( x=> x.Age), minAge = g.Min(x => x.Age), sumAge = g.Sum(x => x.Age), avgAge = g.Average(s => s.Age) }; foreach (var item in queryInfo) { Console.WriteLine($"{item.Key}---总行数:{item.count},最大年龄:{item.maxAge},最小年龄:{item.minAge},年龄和:{item.sumAge},平均年龄:{item.avgAge}"); } ``` 执行结果: ``` Male---总行数:2,最大年龄:19,最小年龄:18,年龄和:37,平均年龄:18.5 Female---总行数:1,最大年龄:17,最小年龄:17,年龄和:17,平均年龄:17 ``` 参考: https://blog.csdn.net/m0_56259289/article/details/144134122 https://blog.csdn.net/qq_34550459/article/details/113540805 https://zhuanlan.zhihu.com/p/146747701 原文出处:http://malaoshi.top/show_1GWo93Q1dMS.html