OWNER CONTENT

输入访问密码

此内容仅主人可见。验证后会回到你刚才的位置。

lin

返回

LINQ 基础#

LINQ(Language Integrated Query,语言集成查询) 是 C# 内置的查询能力,用统一语法操作集合、数据库、XML 等数据源。核心思想:“筛选—投影—排序—分组” 用声明式写法完成。

1. 两种写法#

List<int> nums = new() { 1, 2, 3, 4, 5, 6 };

// 查询语法(类似 SQL,底层会被编译成方法调用)
var query1 = from n in nums
             where n % 2 == 0
             orderby n descending
             select n * 10;

// 方法语法(Lambda,实际开发更常用)
var query2 = nums.Where(n => n % 2 == 0)
                 .OrderByDescending(n => n)
                 .Select(n => n * 10);
// 结果都是 [60, 40, 20]
csharp

大多数情况推荐方法语法,只有多条件 join/分组时查询语法更易读。

2. 常用操作符速查#

筛选与投影#

list.Where(x => x.Age > 18)                 // 筛选
list.Select(x => x.Name)                    // 投影(提取字段/变形)
list.SelectMany(x => x.Tags)                // 拍平嵌套集合
list.Distinct()                             // 去重
csharp

排序#

list.OrderBy(x => x.Age)                    // 升序
list.OrderByDescending(x => x.Age)          // 降序
list.OrderBy(x => x.Age).ThenBy(x => x.Name) // 多级排序
csharp

聚合与判断#

nums.Sum()           nums.Average()          nums.Max() / Min()
nums.Count()         nums.Count(x => x > 3)  // 带条件计数
nums.Any(x => x > 5)                         // 是否存在
nums.All(x => x > 0)                         // 是否全部满足
nums.First()         nums.FirstOrDefault()   // 取第一个(没找到时后者返回默认值)
nums.Single()        nums.SingleOrDefault()  // 确保只有一个
csharp

⚠️ First / Single 找不到元素会抛异常,日常更常用 FirstOrDefault / SingleOrDefault。

分页(搭配常见)#

list.Skip(10).Take(5)      // 跳过10条取5条
csharp

分组与连接#

// 分组
var groups = users.GroupBy(u => u.Dept);
foreach (var g in groups)
    Console.WriteLine($"{g.Key}: {g.Count()}人");

// 连接(类似 SQL JOIN)
var result = from u in users
             join d in depts on u.DeptId equals d.Id
             select new { u.Name, DeptName = d.Name };
csharp

集合运算#

a.Union(b)        // 并集(去重)
a.Intersect(b)    // 交集
a.Except(b)       // 差集
a.Concat(b)       // 拼接(不去重)
a.Contains(x)     // 是否包含
csharp

3. 综合实战#

public class Student
{
    public string Name { get; set; }
    public string ClassName { get; set; }
    public int Score { get; set; }
}

List<Student> students = GetStudents();

// 需求:各班平均分前3名,只要姓名和分数
var top3 = students
    .GroupBy(s => s.ClassName)
    .Select(g => new
    {
        班级 = g.Key,
        平均分 = g.Average(s => s.Score),
        前三 = g.OrderByDescending(s => s.Score)
                .Take(3)
                .Select(s => new { s.Name, s.Score })
    })
    .OrderByDescending(x => x.平均分);
csharp

LINQ 返回的 IEnumerable<T> 常配合匿名类型输出,无需预先定义结果类。

4. 延迟执行(重要概念!)#

var query = nums.Where(n => { Console.WriteLine($"检查{n}"); return n > 2; });
Console.WriteLine("还没开始遍历");
foreach (var n in query) Console.WriteLine(n);  // ⚡ 到这里才真正执行
csharp
  • LINQ 查询默认延迟执行:定义时不做事,遍历时才计算
  • 每次遍历都重新计算,必要时用 ToList() / ToArray() 固化结果:
var list = query.ToList();  // 立即执行并缓存
csharp

5. LINQ 家族#

类型命名空间数据源
LINQ to ObjectsSystem.Linq内存集合(本文内容)
LINQ to Entities(EF Core)Microsoft.EntityFrameworkCore数据库(转成 SQL 执行)
LINQ to XMLSystem.Xml.LinqXML(XDocument)

⚠️ 注意区别:操作内存集合的 LINQ 在 C# 内存中执行;EF Core 的 LINQ 会被翻译成 SQL,部分方法(如自定义方法调用)无法翻译,会报 “could not be translated” 错误。

LINQ 基础
作者 lin
发布于 2026年10月17日

留言

无需登录,留下你的想法。

0
昵称颜色
可见范围