C#零基础通关第十一篇:吃透LINQ核心语法,极简搞定集合查询、筛选、分组、排序

上一篇我们彻底吃透了C#集合体系,搞懂了数组、List、Dictionary、队列、栈的底层原理与业务选型,学会了根据场景选择高性能集合容器,彻底告别集合滥用、性能低效的问题。
我们已经可以熟练存储批量数据,但在数据处理时依然存在痛点:传统for、foreach循环写法繁琐、代码冗余、复用性差。
想要筛选数据、排序、去重、分组、联表查询,动辄十几行循环代码,嵌套逻辑复杂、可读性极低、维护困难。
本篇我们学习C#开发的效率神器——LINQ,这是.NET生态专属的内置数据查询技术,也是日常开发、项目业务、面试高频的核心技能。
学会LINQ,十几行的循环代码可以压缩为一行,极简语法搞定所有集合数据操作,代码更优雅、可读性更强、开发效率翻倍,零基础手把手带你从零吃透。
一、什么是LINQ?核心价值与适用场景
1. LINQ基本定义
LINQ(Language Integrated Query):语言集成查询,是C#内置的一套统一数据查询语法。
通俗理解:专门用来查询、处理数据的语法工具,支持对 数组、List集合、字典、数据库、XML、JSON 等所有数据源进行统一操作。
2. 为什么必须学LINQ?
对比传统循环写法,LINQ拥有碾压级优势:
-
代码极简:告别繁琐for/foreach循环,一行代码实现筛选、排序、分组、去重;
-
语法统一:不管是集合数据还是数据库数据,查询语法基本一致,学习一次通用全场景;
-
可读性强:代码语义化,一眼看懂数据处理逻辑,远优于嵌套循环;
-
性能高效:LINQ底层优化完善,绝大多数场景性能优于手写循环;
-
项目标配:所有.NET项目、Unity开发、后端接口、数据处理全部默认使用LINQ。
3. LINQ两种写法(全部掌握)
-
方法语法(Lambda写法):项目主流、简洁高效、开发首选;
-
查询语法(SQL写法):语义直观、类似SQL语句,适合复杂多条件查询。
二、LINQ前置准备:搭建通用测试数据
后续所有LINQ案例,我们统一使用学生实体集合测试,贴合真实业务场景,方便新手连贯学习。
using System;
using System.Collections.Generic;
using System.Linq;
// 学生实体类
class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
public int Score { get; set; }
}
class Program
{
static void Main()
{
// 初始化测试数据
List<Student> stuList = new List<Student>()
{
new Student(){Id=1,Name="张三",Age=18,Gender="男",Score=85},
new Student(){Id=2,Name="李四",Age=19,Gender="女",Score=92},
new Student(){Id=3,Name="王五",Age=18,Gender="男",Score=78},
new Student(){Id=4,Name="赵六",Age=20,Gender="女",Score=96},
new Student(){Id=5,Name="孙七",Age=19,Gender="男",Score=85}
};
}
}
后续所有筛选、排序、分组案例,均基于以上学生集合数据。
三、核心实战:LINQ常用方法语法(项目首选)
方法语法基于Lambda表达式,链式调用、简洁灵活,是企业开发100%使用的主流写法,下面精讲高频核心方法。
1. Where 条件筛选(最常用)
根据自定义条件过滤数据,返回符合条件的新集合,替代传统if判断+循环筛选。
// 筛选分数大于80分的学生
var goodStu = stuList.Where(s => s.Score > 80).ToList();
// 多条件筛选:18岁以上、男生
var manStu = stuList.Where(s => s.Age >= 18 && s.Gender == "男").ToList();
注意:LINQ查询默认返回迭代器,调用 ToList() 可转为List集合,方便后续操作。
2. OrderBy 排序
对集合数据进行升序/降序排序,支持单字段、多字段排序。
// 按分数升序排序(从小到大)
var ascStu = stuList.OrderBy(s => s.Score).ToList();
// 按分数降序排序(从大到小)
var descStu = stuList.OrderByDescending(s => s.Score).ToList();
// 多字段排序:先按分数降序,分数相同按年龄升序
var multiSort = stuList.OrderByDescending(s => s.Score).ThenBy(s => s.Age).ToList();
3. Select 投影查询(字段筛选)
只查询需要的字段,屏蔽冗余字段,支持自定义返回数据结构,优化数据展示。
// 只查询学生姓名和分数
var stuInfo = stuList.Select(s => new { s.Name, s.Score }).ToList();
// 遍历输出投影数据
foreach (var item in stuInfo)
{
Console.WriteLine($"姓名:{item.Name},分数:{item.Score}");
}
核心场景:接口返回数据、数据展示时,只返回必要字段,避免数据冗余泄露。
4. First/FirstOrDefault 取首条数据
获取符合条件的第一条数据,解决循环取单条数据的冗余写法。
// 获取分数最高的学生(无数据会报错)
var firstStu = stuList.OrderByDescending(s => s.Score).First();
// 安全获取:无数据返回null,项目首选(杜绝报错)
var safeStu = stuList.Where(s => s.Score > 100).FirstOrDefault();
5. 常用聚合函数(统计数据)
一行代码实现最大值、最小值、平均值、总数、求和,无需手动循环统计。
// 学生总数
int count = stuList.Count();
// 最高分
int maxScore = stuList.Max(s => s.Score);
// 最低分
int minScore = stuList.Min(s => s.Score);
// 平均分
double avgScore = stuList.Average(s => s.Score);
// 分数总和
int sumScore = stuList.Sum(s => s.Score);
Console.WriteLine($"总数:{count},最高分:{maxScore},平均分:{avgScore}");
6. Distinct 去重
快速去除集合重复数据,支持基础类型、自定义实体去重。
// 提取所有不重复的年龄
var ageList = stuList.Select(s => s.Age).Distinct().ToList();
7. Any 存在判断
判断是否存在符合条件的数据,返回布尔值,替代Count判断,性能更高。
// 判断是否有90分以上的学生
bool hasHigh = stuList.Any(s => s.Score > 90);
// 判断集合是否为空
bool isEmpty = !stuList.Any();
四、LINQ查询语法(SQL风格)
查询语法类似SQL语句,语义通俗易懂,适合新手理解复杂查询逻辑,日常开发可按需选用。
// 查询语法:筛选80分以上、按分数降序、只查姓名和分数
var queryStu = from s in stuList
where s.Score > 80
orderby s.Score descending
select new { s.Name, s.Score };
// 遍历结果
foreach (var item in queryStu)
{
Console.WriteLine($"{item.Name}:{item.Score}分");
}
开发建议:简单查询用方法语法,复杂多条件、多关联查询用查询语法,灵活搭配。
五、高阶核心:GroupBy 分组查询(面试高频)
分组是LINQ的高阶核心功能,可根据指定字段对数据分组统计,替代复杂嵌套循环,适合分类统计、报表数据生成场景。
// 根据性别分组,统计每组人数、平均分
var groupStu = stuList.GroupBy(s => s.Gender).ToList();
foreach (var group in groupStu)
{
Console.WriteLine($"性别:{group.Key}");
Console.WriteLine($"人数:{group.Count()}");
Console.WriteLine($"平均分:{group.Average(s => s.Score):f2}");
}
核心解析:GroupBy 返回分组集合,Key为分组字段值,组内可继续统计、筛选、排序。
六、LINQ链式编程(企业标准写法)
真实项目中,所有LINQ方法支持链式连续调用,一行代码完成筛选、排序、投影、去重全套操作,极度简洁。
// 完整链式操作:筛选18岁以上 - 按分数降序 - 只取姓名分数 - 转为集合
var result = stuList
.Where(s => s.Age >= 18)
.OrderByDescending(s => s.Score)
.Select(s => new { s.Name, s.Age, s.Score })
.ToList();
这是企业项目中最标准、最高频的LINQ写法,简洁优雅、逻辑清晰。
七、LINQ延迟执行(底层核心、面试必考)
90%新手不懂LINQ底层机制,导致出现数据错乱、重复查询问题,这是LINQ最重要的底层特性。
1. 延迟执行原理
LINQ查询默认是延迟执行(懒加载):定义查询语句时,不会立刻执行查询,只有在遍历、取值、转换集合(ToList、First、Count)时,才会真正执行。
2. 实战验证
// 仅定义查询,未执行
var query = stuList.Where(s => s.Score > 80);
// 此时修改原集合数据
stuList[0].Score = 90;
// 取值时才执行查询,会读取修改后的最新数据
var res = query.ToList();
3. 强制立即执行方法
以下方法会触发LINQ立即执行,缓存查询结果:ToList()、ToArray()、First()、Count()、Sum() 等。
开发避坑:需要固定查询结果时,立即调用ToList()缓存数据,避免后续原数据修改导致结果变动。
八、新手高频易错坑点(必避)
-
忘记引用命名空间:使用LINQ必须引用
using System.Linq;,否则所有LINQ方法报错; -
空数据报错:优先使用
FirstOrDefault、SingleOrDefault,杜绝First直接取值空数据报错; -
忽略延迟执行:未ToList缓存的查询,多次取值会重复查询,且读取最新数据;
-
条件逻辑混乱:多条件筛选合理使用&&、||,避免逻辑颠倒导致数据筛选错误;
-
过度使用LINQ:极简单的取值、遍历无需LINQ,避免过度封装影响可读性。
九、全文核心总结
-
LINQ本质:C#内置统一查询语法,极简处理数组、集合、数据库等各类数据源;
-
两种写法:Lambda方法语法简洁高效(项目首选),SQL查询语法语义直观(适合复杂查询);
-
核心高频方法:Where筛选、OrderBy排序、Select投影、GroupBy分组、聚合统计、Any判断;
-
链式编程:多方法连续调用,一行代码完成复杂数据处理,代码极简优雅;
-
延迟执行:LINQ默认懒加载,取值时执行,ToList可缓存结果,是底层核心特性。
LINQ是.NET开发的效率核心,熟练掌握后可彻底告别冗余循环代码,是进阶规范开发、对接数据库、接口开发的必备技能。
下期预告
下一篇我们将精讲 C# 异常处理机制,彻底解决程序崩溃、报错闪退问题,学会优雅捕获、处理、抛出异常,写出健壮性极强的项目代码!
更多推荐



所有评论(0)