var orderDetails = from o in orders join p in products on o.ProductId equals p.Id group o by p.Category into g selectnew { Category = g.Key, TotalAmount = g.Sum(o => o.Amount) };
2. 延迟执行(Deferred
Execution)
这是 LINQ 最重要的特性,也是最容易踩坑的地方。
1 2 3 4 5 6 7 8
var query = users.Where(u => u.IsActive); // 此时没有执行任何查询
Console.WriteLine("查询还没开始");
foreach (var user in query) // 迭代时才真正执行 { Console.WriteLine(user.Name); }
陷阱一:多次枚举
1 2 3 4 5 6 7 8 9
var activeUsers = users.Where(u => u.IsActive);
int count = activeUsers.Count(); // 第一次遍历 var list = activeUsers.ToList(); // 第二次遍历 — 重复计算!
// 正确做法:物化一次 var activeUsersList = users.Where(u => u.IsActive).ToList(); int count2 = activeUsersList.Count; var list2 = activeUsersList;
陷阱二:闭包捕获变量
1 2 3 4 5 6 7 8 9 10 11 12 13
var queries = new List<IEnumerable<User>>(); for (int i = 0; i < 3; i++) { // 错误:所有 query 都捕获了同一个 i,最终都是 i=3 queries.Add(users.Where(u => u.DeptId == i)); }
// 正确:在循环内创建局部变量 for (int i = 0; i < 3; i++) { int deptId = i; queries.Add(users.Where(u => u.DeptId == deptId)); }
3. 常用操作符详解
3.1 聚合操作
1 2 3 4 5 6 7 8
var stats = users.Where(u => u.IsActive) .GroupBy(u => u.Department) .Select(g => new { Department = g.Key, Count = g.Count(), AvgAge = g.Average(u => u.Age), MaxSalary = g.Max(u => u.Salary) });