C#:LINQ学习笔记01:LINQ基础概念
一、LINQ 架构体系
1. LINQ 的核心思想
- 统一查询模型:对对象、XML、数据库等不同数据源使用一致的语法。
- 强类型检查:编译时类型安全,减少运行时错误。
2. 核心组件
技术 | 数据源 | 典型场景 |
---|---|---|
LINQ to Objects | 内存集合 (IEnumerable ) | 过滤/排序集合数据 |
LINQ to XML | XML 文档 | 解析/查询 XML 节点 |
LINQ to SQL | 关系数据库 | 将查询翻译为 SQL 执行 |
关键代码示例:
// LINQ to Objects
var numbers = new List<int> { 1, 2, 3 };
var query = numbers.Where(n => n > 1);
// LINQ to XML
XDocument doc = XDocument.Load("data.xml");
var elements = doc.Descendants("Book").Where(x => (int)x.Element("Price") > 50);
// LINQ to SQL(伪代码)
var db = new DataContext();
var users = db.Users.Where(u => u.Age > 18);
二、查询表达式 vs 方法语法
1. 本质区别
- 查询表达式:类 SQL 语法(
from...where...select
),可读性高。 - 方法语法:链式调用扩展方法(
Where()
/Select()
),灵活性更强。
2. 转换关系
所有查询表达式会被编译器翻译为方法语法。
代码对比:
// 查询表达式
var query1 = from num in numbers
where num % 2 == 0
select num * 2;
// 方法语法
var query2 = numbers
.Where(num => num % 2 == 0)
.Select(num => num * 2);
三、IEnumerable 接口解析
1. 核心机制
IEnumerable
:定义迭代能力(通过GetEnumerator()
)。IEnumerator
:实现遍历逻辑(MoveNext()
和Current
)。
2. LINQ 的延迟执行
- 查询定义时不执行,直到迭代结果(如
foreach
或ToList()
)时才触发。
代码验证延迟执行:
var numbers = new List<int> { 1, 2, 3 };
var query = numbers.Select(n => {
Console.WriteLine($"Processing {n}");
return n * 2;
});
// 此时无输出
foreach (var num in query) { } // 输出:Processing 1, Processing 2, Processing 3
四、创建首个 LINQ 查询(三步法)
1. 定义数据源
var products = new List<Product> {
new Product { Name = "Apple", Price = 15 },
new Product { Name = "Laptop", Price = 5000 },
new Product { Name = "Book", Price = 80 }
};
2. 编写查询
// 方法语法
var expensiveProducts = products
.Where(p => p.Price > 100)
.OrderBy(p => p.Name);
3. 执行查询
foreach (var product in expensiveProducts)
{
Console.WriteLine(product.Name);
}
五、练习:集合过滤与投影
任务 1:过滤数据
// 数据源
var numbers = Enumerable.Range(1, 100);
// 目标:选出 3 的倍数且大于 50 的数字
var result = numbers.Where(n => n % 3 == 0 && n > 50);
任务 2:投影转换
// 数据源
var persons = new List<Person> { /* 包含姓名和年龄的对象 */ };
// 目标:生成 { Name = "张三", Initial = 'Z' } 形式的新对象
var initials = persons.Select(p => new {
Name = p.Name,
Initial = p.Name[0]
});
六、扩展思考
- 如何通过
yield return
自定义一个延迟执行的 LINQ 操作? IQueryable
和IEnumerable
在查询数据库时的区别?- 如何组合
Where().OrderBy().Select()
实现复杂查询?