C# LINQ 查询关键字详解与实战代码

Oliver
Oliver
发布时间:2026-10-14| 6人浏览过
原创

本文深入解析 C# LINQ 的核心语法,通过具体的代码实例展示 from、where、select、group、join、orderby 和 let 等关键字的用法,覆盖基础筛选到复杂的多表连接场景。

准备条件

在开始使用 LINQ 之前,需要确保项目中引入了 System.Linq 命名空间。LINQ 允许开发者以类似 SQL 的语法对内存中的对象集合(如 List<T>)进行查询。本文将基于标准的 .NET Console 应用程序环境进行演示,数据类型包括基础字符串数组和自定义类。

LINQ 基本操作关键字详解

第1步:from 子句 - 指定数据源

from 是 LINQ 查询的表达式的起点,用于声明范围变量和数据源。它告诉编译器要遍历哪个集合以及每个元素的临时名称。

复制代码 代码如下:
// 基础形式
var query = from item in sourceCollection
            select item;

// 复合 from:当源元素本身也是集合时
// 例如:获取列表中所有分数大于90的学生及其分数
var query = from student in students 
            from score in student.Scores 
            where score > 90 
            select new { LastName = student.LastName, Score = score };

复合 from 常用于处理嵌套结构,例如一个学生对象中包含一个分数列表,此时需要在查询中对内部的 Scores 列表进行扁平化处理。

第2步:where 子句 - 过滤数据

where 子句用于定义筛选条件,只有满足条件的元素才会被包含在结果集中。它可以包含多个由 && 或 || 连接的谓词。

复制代码 代码如下:
string[] words = { "apple", "bat", "avocado" };
var filteredWords = from w in words 
                    where w.Contains("a") 
                    select w;

第3步:orderby 子句 - 排序结果

orderby 用于对查询结果进行排序。默认情况下为升序(ascending),可以通过添加 descending 关键字实现降序排列。支持多键排序,后续的键会自动转换为 ThenBy 或 ThenByDescending。

复制代码 代码如下:
// 升序
var ascQuery = from s in str orderby s ascending select s;

// 降序
var descQuery = from s in str orderby s descending select s;

第4步:select 子句 - 投影结果

select 用于指定查询返回的形状。它可以返回原始对象,也可以创建一个新的匿名类型,仅包含需要的属性,从而优化内存使用和后续处理。

第5步:let 子句 - 存储计算中间结果

let 关键字用于引入一个新的范围变量,并储存其运算结果。这在表达式较长或在多个地方需要重复使用同一计算结果时非常有用,能提高可读性。

复制代码 代码如下:
// 示例:找出首字母为 'a' 或 'e' 的单词
var query = from sentence in strings
            let words = sentence.Split(' ') // 分割句子
            from word in words
            let w = word.ToLower()          // 统一转为小写
            where w[0] == 'a' || w[0] == 'e'
            select word;

第6步:group by 子句 - 数据分组

group ... by ... into ... 用于将元素按键值分组。返回类型为 IGrouping< TKey, TElement>。into 在此处创建一个标识符,以便对分组后的结果继续进行操作(如再次筛选或选择特定字段)。

复制代码 代码如下:
string[] str = { "aa", "bb", "cc", "dd" };
var query = from s in str
            group s by s[0] // 按第一个字符分组
            into g           // 命名为g
            where g.Key == 'a' || g.Key == 'b' || g.Key == 'c'
            orderby g.Key descending
            select g.Key;
// 输出: c b a

高级操作:Join 连接查询

join 用于关联两个不同的数据源,前提是它们之间存在公共键。LINQ 中使用 equals 关键字进行比较,而非 ==。

1. 内部连接 (Inner Join)

只返回两个序列中匹配的记录。

复制代码 代码如下:
var query = from a in collectionA
            join b in collectionB on a.Id equals b.Id
            select new { NameA = a.Name, NameB = b.Name };

2. 分组连接 (Group Join)

类似于 SQL 中的分组,将右表的匹配项聚合为一个集合。

复制代码 代码如下:
var query = from a in collectionA
            join b in collectionB on a.Id equals b.Id
            into resultGroups
            select new { AName = a.Name, Matches = resultGroups };

3. 左外部连接 (Left Outer Join)

返回左序列的所有元素,即使它们在右序列中没有匹配项。通过使用 DefaultIfEmpty() 来实现,当没有匹配时返回默认值(如 null 或空对象)。

复制代码 代码如下:
var query = from category in categories
            join prod in products on category.Id equals prod.CategoryId
            into prodGroup
            from item in prodGroup.DefaultIfEmpty(new Product{Name = string.Empty, CategoryId = 0})
            select new { CatName = category.Name, ProdName = item.Name };

复合键与多字段比较

当需要根据多个字段判断相等性时,可以使用匿名对象作为连接键。编译器会比较这两个对象的各属性是否分别相等。

复制代码 代码如下:
var query = from p1 in persons
            join p2 in persons on new { Id1 = p1.Id1, Id2 = p1.Id2 } 
                                 equals new { Id1 = p2.Id1, Id2 = p2.Id2 }
            select new { p1.Name, p2.Relation };

实体定义参考

以下为学生和员工的简单类定义,供上述部分示例参考:

复制代码 代码如下:
public class Student {
    public string LastName { get; set; }
    public List<int> Scores { get; set; }
}

public class Employee {
    public string First { get; set; }
    public string Last { get; set; }
    public int ID { get; set; }
}

执行结果说明

以复合 From 查询为例,假设有学生列表如下:

  • xiaogui: Scores = {97, 42, 91, 60}
  • xiaozhan: Scores = {50, 92, 81, 60}
  • xiaowan: Scores = {92, 22, 81, 60}

查询 score > 90 的结果将打印:

  • xiaogui Score:97
  • xiaogui Score:91
  • xiaozhan Score:92
  • xiaowan Score:92

总结

LINQ 提供了强大且直观的查询能力,通过组合 from、where、select、join、group 等关键字,可以优雅地处理复杂的业务逻辑。掌握这些基本操作是编写高效 C# 数据处理代码的关键。以上就是 C# LINQ 查询基本操作的详细内容,更多关于 C# LINQ 进阶技巧的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。