GroupJoin 是 LINQ 中一个强大但较难理解的操作符,它结合了 Join 和 Group 的功能
1. 基本语法
var result = outer.GroupJoin(inner,
outerKeySelector,
innerKeySelector,
resultSelector);
2. 实际示例
基础示例
// 定义数据
var departments = new List<Department>
{
new Department { Id = 1, Name = "IT" },
new Department { Id = 2, Name = "HR" }
};
var employees = new List<Employee>
{
new Employee { Id = 1, Name = "张三", DeptId = 1 },
new Employee { Id = 2, Name = "李四", DeptId = 1 },
new Employee { Id = 3, Name = "王五", DeptId = 2 }
};
// 使用 GroupJoin
var result = departments.GroupJoin(employees,
dept => dept.Id, // 外部序列键选择器
emp => emp.DeptId, // 内部序列键选择器
(dept, emps) => new { // 结果选择器
Department = dept.Name,
Employees = emps.ToList()
});
查询语法形式
var result = from dept in departments
join emp in employees
on dept.Id equals emp.DeptId
into empGroup
select new {
Department = dept.Name,
Employees = empGroup
};
3. 高级用法
多重条件 GroupJoin
var result = departments.GroupJoin(employees,
dept => new { Id = dept.Id, Active = true },
emp => new { Id = emp.DeptId, Active = emp.IsActive },
(dept, emps) => new {
Department = dept.Name,
ActiveEmployees = emps.ToList()
});
带默认值的 GroupJoin
var result = departments.GroupJoin(employees,
dept => dept.Id,
emp => emp.DeptId,
(dept, emps) => new {
Department = dept.Name,
EmployeeCount = emps.Count(),
Employees = emps.DefaultIfEmpty(new Employee { Name = "无员工" })
});
4. 注意事项
性能考虑
- GroupJoin 会创建临时集合
- 大数据量时要注意内存使用
- 考虑使用索引优化查询
空值处理
- 使用 DefaultIfEmpty 处理空集合
- 注意 null 检查
- 考虑使用空合并运算符
常见错误
- 键选择器返回类型不匹配
- 忘记处理空集合
- 重复键的处理
5. 使用场景
一对多关系查询
- 层级数据结构构建
- 数据分组统计
- 复杂报表生成
GroupJoin 虽然复杂,但在处理一对多关系和数据分组时非常有用,掌握它可以大大提高数据处理能力