📅 Day 22:LINQ(Language Integrated Query)
✅ 学习目标:
- 理解什么是 LINQ,及其在 C# 中的作用;
- 掌握使用 LINQ 查询语法(Query Syntax) 和 方法语法(Method Syntax);
- 熟悉常用 LINQ 操作符(如
Where
、Select
、OrderBy
、GroupBy
等); - 能够对集合、数组、数据库、XML 进行查询操作;
- 理解延迟执行和立即执行的区别;
- 编写一个完整的 LINQ 示例程序,如学生管理系统查询模块;
- 初步了解 LINQ to SQL / Entity Framework 的应用场景。
🧠 一、什么是 LINQ?
LINQ(Language Integrated Query) 是 C# 提供的一种统一的查询语言,它将数据查询集成到 C# 语言中,使得你可以用类似 SQL 的方式来查询各种数据源(如集合、数据库、XML 等)。
主要优点:
特性 | 描述 |
---|---|
类型安全 | 在编译时检查错误 |
可读性强 | 使用声明式语法,代码更清晰 |
统一查询模型 | 支持多种数据源(内存对象、SQL、XML 等) |
🔁 二、LINQ 的两种语法风格
1. 查询语法(Query Syntax)—— 类似 SQL
var query = from item in collection
where item.Property > 10
select item;
2. 方法语法(Method Syntax)—— 使用 Lambda 表达式
var query = collection.Where(item => item.Property > 10);
✅ 实际上两者是等价的,编译器会把查询语法转换为方法语法。
🧩 三、常见 LINQ 操作符
操作符 | 功能 |
---|---|
Where |
过滤元素 |
Select |
投影(映射) |
OrderBy / OrderByDescending |
排序 |
ThenBy / ThenByDescending |
多字段排序 |
GroupBy |
分组 |
Join |
内连接 |
GroupJoin |
分组连接 |
Distinct |
去重 |
Skip / Take |
分页 |
First / FirstOrDefault |
获取第一个元素 |
Single / SingleOrDefault |
获取唯一元素 |
Count / Sum / Average / Min / Max |
聚合操作 |
🧱 四、基本 LINQ 示例
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
// 查询语法
var evenNumbersQuery = from n in numbers
where n % 2 == 0
select n;
// 方法语法
var evenNumbersMethod = numbers.Where(n => n % 2 == 0);
foreach (var num in evenNumbersQuery)
{
Console.WriteLine(num);
}
🔄 五、延迟执行 vs 立即执行
✅ 延迟执行(Deferred Execution)
大多数 LINQ 操作符不会立即执行,而是等到你遍历结果(如 foreach
)时才真正执行。
var query = numbers.Where(n => n > 3); // 此时尚未执行
numbers.Add(10); // 修改原集合
foreach (var n in query) // 此时执行,包含新值
Console.WriteLine(n);
✅ 立即执行(Immediate Execution)
某些方法会在调用时立即执行并返回结果:
方法 | 说明 |
---|---|
ToList() |
返回 List<T> |
ToArray() |
返回数组 |
ToDictionary() |
返回字典 |
Count() |
返回数量 |
First() / Last() |
获取单个元素 |
💡 六、LINQ 查询复杂对象示例
class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Score { get; set; }
}
List<Student> students = new List<Student>
{
new Student { Id = 1, Name = "张三", Score = 85 },
new Student { Id = 2, Name = "李四", Score = 92 },
new Student { Id = 3, Name = "王五", Score = 78 },
};
// 查询语法
var topStudents = from s in students
where s.Score >= 90
orderby s.Name descending
select s;
// 方法语法
var topStudentsMethod = students
.Where(s => s.Score >= 90)
.OrderByDescending(s => s.Name);
foreach (var student in topStudents)
{
Console.WriteLine($"{student.Id} - {student.Name} : {student.Score}");
}
🧪 七、分组查询(GroupBy)
var grouped = from s in students
group s by s.Score / 10 into g
orderby g.Key descending
select new { Grade = g.Key * 10, Students = g };
foreach (var group in grouped)
{
Console.WriteLine($"分数段:{group.Grade}-{group.Grade + 9}");
foreach (var student in group.Students)
{
Console.WriteLine(" " + student.Name);
}
}
🔗 八、LINQ Join 示例(内连接)
class Order
{
public int Id { get; set; }
public int StudentId { get; set; }
public decimal Amount { get; set; }
}
List<Order> orders = new List<Order>
{
new Order { Id = 1, StudentId = 1, Amount = 100 },
new Order { Id = 2, StudentId = 2, Amount = 200 },
};
// 查询语法
var query = from s in students
join o in orders on s.Id equals o.StudentId
select new { s.Name, o.Amount };
// 方法语法
var method = students.Join(
orders,
s => s.Id,
o => o.StudentId,
(s, o) => new { s.Name, o.Amount });
foreach (var item in query)
{
Console.WriteLine($"{item.Name} - {item.Amount}");
}
🧮 九、聚合函数(Aggregation)
int count = students.Count();
decimal total = orders.Sum(o => o.Amount);
decimal average = orders.Average(o => o.Amount);
Student topStudent = students.OrderByDescending(s => s.Score).First();
📝 十、LINQ to Objects、LINQ to SQL、LINQ to XML
LINQ 类型 | 数据源 | 用途 |
---|---|---|
LINQ to Objects | 集合、数组 | 内存中查询 |
LINQ to SQL | SQL Server 数据库 | 简单 ORM |
LINQ to Entities | Entity Framework | ORM 扩展 |
LINQ to XML | XML 文档 | XML 解析/生成 |
💪 实战练习:学生信息查询系统
功能要求:
- 定义
Student
类,包含姓名、年龄、成绩; - 创建多个学生对象;
- 实现以下功能:
- 查询所有及格的学生;
- 查询最高分和平均分;
- 按成绩降序排列输出;
- 将结果保存为列表或数组。
示例代码:
class Program
{
static void Main()
{
List<Student> students = new List<Student>
{
new Student { Name = "张三", Age = 20, Score = 88 },
new Student { Name = "李四", Age = 22, Score = 95 },
new Student { Name = "王五", Age = 21, Score = 70 },
new Student { Name = "赵六", Age = 19, Score = 65 },
};
var passed = students.Where(s => s.Score >= 60);
var topScore = students.Max(s => s.Score);
var avgScore = students.Average(s => s.Score);
var sorted = students.OrderByDescending(s => s.Score);
Console.WriteLine("及格学生:");
foreach (var s in passed)
{
Console.WriteLine($"{s.Name} - {s.Score}");
}
Console.WriteLine($"\n最高分:{topScore}");
Console.WriteLine($"平均分:{avgScore:F2}");
Console.WriteLine("\n按成绩排序:");
foreach (var s in sorted)
{
Console.WriteLine($"{s.Name} - {s.Score}");
}
}
}
class Student
{
public string Name { get; set; }
public int Age { get; set; }
public int Score { get; set; }
}
📝 小结
今天你学会了:
- 什么是 LINQ,它在 C# 中的作用;
- 掌握了 LINQ 的两种语法风格(查询语法 & 方法语法);
- 熟悉了常见的 LINQ 操作符(如 Where、Select、OrderBy、GroupBy、Join);
- 理解了延迟执行与立即执行的区别;
- 编写了多个 LINQ 示例,包括查询、排序、分组、连接等;
- 初步了解了 LINQ to SQL 和 LINQ to XML 的应用场景。
LINQ 是现代 C# 开发中不可或缺的工具之一,掌握它可以显著提升你在处理集合、数据库、XML 等数据源时的效率和代码可读性。
🧩 下一步学习方向(Day 23)
明天我们将进入一个新的主题 —— 表达式树(Expression Trees)与动态查询构建,你将学会如何使用表达式树构建动态 LINQ 查询、实现条件筛选、自定义查询逻辑等高级技巧。