文章目录

C# LINQ:查询语法与方法语法的使用

发布于 2026-04-03 15:55:06 · 浏览 6 次 · 评论 0 条

C# LINQ:查询语法与方法语法的使用

LINQ(Language Integrated Query)是 C# 中用于操作数据集合的强大工具。它允许你像写 SQL 一样从数组、列表、数据库等数据源中筛选、排序和转换数据。LINQ 提供两种写法:查询语法(Query Syntax)和方法语法(Method Syntax)。两者功能完全等价,只是写法不同。下面直接教你如何使用。


查询语法:像写 SQL 一样查数据

查询语法看起来更接近 SQL,适合复杂查询或多步骤筛选。

  1. 声明一个数据源。例如,创建一个整数列表:

    var numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
  2. from ... where ... select 写查询。例如,找出所有大于 5 的偶数:

    var result = from n in numbers
                 where n > 5 && n % 2 == 0
                 select n;
  3. 执行查询并输出结果。注意:LINQ 查询是“延迟执行”的,只有在遍历时才真正运行:

    foreach (var item in result)
    {
        Console.WriteLine(item); // 输出 6, 8, 10
    }
  4. 支持多条件排序。例如,先按长度降序,再按字母升序(适用于字符串):

    var words = new List<string> { "apple", "fig", "banana", "cherry" };
    var sorted = from w in words
                 orderby w.Length descending, w ascending
                 select w;
  5. 可以投影新对象。例如,把每个数字变成匿名对象:

    var info = from n in numbers
               where n % 2 == 0
               select new { Value = n, IsEven = true };

方法语法:用链式调用操作数据

方法语法使用扩展方法(如 WhereSelectOrderBy),适合简单操作或函数式风格。

  1. 对同一数据源使用方法链。上面“大于 5 的偶数”例子改写为:

    var result = numbers.Where(n => n > 5).Where(n => n % 2 == 0);

    或合并条件:

    var result = numbers.Where(n => n > 5 && n % 2 == 0);
  2. 常用方法直接调用

    • 筛选Where(condition)
    • 投影Select(transformer)
    • 排序OrderBy(key)OrderByDescending(key)
    • 去重Distinct()
    • 取前 N 项Take(n)
    • 跳过前 N 项Skip(n)
  3. 组合多个操作。例如,取前 3 个大于 3 的偶数并平方:

    var squares = numbers
        .Where(n => n > 3 && n % 2 == 0)
        .Take(3)
        .Select(n => n * n);
  4. 立即执行的方法。有些方法会立刻计算结果(而非延迟):

    • ToList():转成 List<T>
    • ToArray():转成数组
    • Count():返回元素数量
    • First() / FirstOrDefault():取第一个元素

    示例:

    var list = numbers.Where(n => n < 5).ToList();

查询语法 vs 方法语法:怎么选?

两种语法可互相转换,选择取决于场景和个人习惯。以下是对比:

特性 查询语法 方法语法
可读性(复杂查询) 更高(类似 SQL) 较低(嵌套 lambda)
可读性(简单操作) 略显冗长 更简洁
支持的操作 大部分常见操作 全部 LINQ 操作(如 Aggregate, Zip
学习曲线 对 SQL 用户友好 对函数式编程用户友好
调试便利性 难以单步调试中间步骤 可拆分为多行,方便调试

关键结论:复杂多表关联或嵌套查询用查询语法;简单过滤、转换或需要调用特殊方法时用方法语法


实战:两种语法混合使用

实际开发中,经常混合使用两种语法以发挥各自优势。

  1. 先用查询语法做主体筛选

    var query = from p in products
                where p.Price < 100
                orderby p.Name
                select p;
  2. 再用方法语法追加操作

    var finalList = query.Take(10).ToList();
  3. 或者反过来:先用方法语法预处理,再用查询语法细化:

    var cheapProducts = products.Where(p => p.Price < 50);
    var result = from p in cheapProducts
                 where p.Category == "Electronics"
                 select p.Name.ToUpper();

注意事项与最佳实践

  1. 避免重复执行。LINQ 查询每次遍历都会重新计算。如果多次使用结果,调用 ToList()ToArray() 缓存

    var cached = data.Where(x => x.IsValid).ToList(); // 执行一次
  2. 不要在循环中定义 LINQ 查询。这会导致每次迭代都重新构建表达式树,影响性能。

  3. 优先使用方法语法调用非查询操作。例如,Count()Any()Sum() 等聚合方法在方法语法中更自然:

    bool hasExpensive = products.Any(p => p.Price > 1000);
  4. 命名清晰的变量。无论哪种语法,变量名应反映其含义:

    var affordablePhones = from p in products
                           where p.Category == "Phone" && p.Price < 500
                           select p;
  5. 理解延迟执行。以下代码不会立即运行查询:

    var q = numbers.Where(n => n > 0); // 此时未执行
    numbers.Add(999); // 修改原列表
    var list = q.ToList(); // 此时执行,包含 999

立即执行可避免此类副作用。

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文