CodeGym /课程 /C# SELF /LINQ语法:Method Syntax vs Query Syntax

LINQ语法:Method Syntax vs Query Syntax

C# SELF
第 31 级, 课程 1
可用

1. 入门

在LINQ的世界里,其实有两大“流派”写查询,两种风格,乍一看好像完全不一样。就是Query Syntax(查询语法)和Method Syntax(方法语法)。如果你一直觉得编程就是死板的逻辑,那今天我们要加点艺术感,因为选语法风格有点像选画笔还是铅笔:都能画画,但一个更适合上色,一个更适合勾线。

为啥要有两种语法?好问题!想象下你点咖啡。你可以说:“麻烦来一杯加牛奶和一勺糖的意式浓缩?”。也可以写在纸上:“意式浓缩。牛奶。1糖”。两种都能懂,但一个更口语,一个更简洁。

LINQ也是这样。一种语法就是为了让你写起来像SQL数据库那样,另一种更“C#风格”也更灵活。其实C#编译器最后都会把这两种写法转成一样的:方法调用。所以选哪个,主要看你觉得哪个更好读、自己喜欢哪个。

我们来看看这两种写法。

2. Method Syntax

这种写法就是你把LINQ的扩展方法一个个点出来连着用。这种方式在.NET开发者里特别流行,因为很容易加新操作,结果总是IEnumerable<T>,而且直接在代码里写很顺手。

例子:筛选并排序商品


var filteredProducts = products
    .Where(p => p.Price < 1000)          // 按价格筛选
    .OrderBy(p => p.Name)                // 按名字排序
    .ToList();                           // 转成 List<Product>

Where、OrderBy 和 ToList 都是LINQ的扩展方法,每个都会返回一个新的数据集,可以继续链式处理。

流程图


graph LR
A[products] --> B[Where]
B --> C[OrderBy]
C --> D[ToList]
Method Syntax的调用顺序

Method Syntax的优点

  • 超灵活:可以很容易地拼出很复杂的操作链。
  • 所有方法都是C#方法,IDE会自动补全。
  • 几乎LINQ能做的事都能做(甚至还能更多)。

再举个例子:选出所有18岁以上用户的名字

假设我们有个User类:


public class User
{
    public string Name { get; set; }
    public int Age { get; set; }
}

现在选出成年用户的名字:


List<User> users = ... // 某处声明的

var adultNames = users
    .Where(u => u.Age >= 18)
    .Select(u => u.Name)
    .ToList();

3. Query Syntax(SQL风格语法)

这种语法就是专门让C#开发者有种写SQL的感觉。如果你以前写过SQL数据库,这种写法会很亲切。它以from关键字开头。

例子:同样的筛选和排序


var filteredProducts = 
    from p in products
    where p.Price < 1000
    orderby p.Name
    select p;

这就像经典的SQL查询:“从products里拿p,p.Price < 1000,按p.Name排序,选p”。

流程图


flowchart TD
    A[products] -->|from p in products| B[where p.Price < 1000]
    B --> C[orderby p.Name]
    C --> D[select p]
Query Syntax的查询步骤

Query Syntax的优点

  • 像SQL,数据库老手一看就懂。
  • 写多条件、分组、连接(join)时更清晰。

再举个例子:选出成年用户的名字


var adultNames = 
    from u in users
    where u.Age >= 18
    select u.Name;

注意:这里select后面可以直接选字段,比如只要名字,不用整个对象。

4. 对比:Method Syntax vs Query Syntax

Method Syntax Query Syntax
语法
users.Where(...).Select(...)
from u in users where ... select ...
像什么 普通方法/链式调用 SQL
适用场景 任何操作都能用 不是所有操作都能用(比如
Sum
、
Count
只能Method Syntax)
可读性 链式操作很清楚 分组、连接时更方便
返回什么 通常是
IEnumerable<T>
通常是
IEnumerable<T>
,但有时要
.ToList()
变成列表

现实生活中的有趣事实

微软官方LINQ文档里的例子,基本都是两种写法都给你。但实际项目里,Method Syntax用得更多——因为链扩展方法(Where、Select、OrderBy等)更顺手。

混用还是不混用?怎么选风格

可以在一个项目里混着用两种语法(甚至一个查询里都能混,不过那样看着怪怪的)。最重要的是别把代码写成大杂烩。一般一个模块或项目选一种风格,这样代码更好读。

Method Syntax特别适合连续转换和用所有LINQ方法(有些方法只有方法写法,比如Sum、Count、Any等)。

Query Syntax在有join、group by或多层复杂条件时,读起来更舒服。

5. 风格转换:其实本质都一样

C#里的LINQ会把所有SQL风格的查询(Query Syntax)转成方法链(Method Syntax)。也就是说,不管你怎么写,C#编译时都会变成扩展方法。

例1——筛选:

Query Syntax:


var adults = from u in users
             where u.Age >= 18
             select u;

Method Syntax(等价):


var adults = users.Where(u => u.Age >= 18);

例2——字段选择(Select):

Query Syntax:


var names = from u in users
            select u.Name;

Method Syntax:


var names = users.Select(u => u.Name);

7. 分组和连接(join、group by)

创建新对象

我们给学习项目加个功能,显示按年龄分组的用户列表。这时候两种语法的差别就很明显了。

Query Syntax(分组):


var usersByAge = 
    from u in users
    group u by u.Age into ageGroup
    select new { Age = ageGroup.Key, Users = ageGroup.ToList() };

我们按年龄分组用户(group u by u.Age)。into后面出现的ageGroup就是分组对象。

Method Syntax(等价):


var usersByAge = users
    .GroupBy(u => u.Age)
    .Select(ageGroup => new { Age = ageGroup.Key, Users = ageGroup.ToList() });

再复杂点:连接(join)

假设我们有订单列表(orders)和用户列表(users)。我们想得到用户名字和他们订单的总额。

Query Syntax:


var userOrders =
    from user in users
    join order in orders on user.Id equals order.UserId
    select new { user.Name, order.Amount };

Method Syntax:


var userOrders = users.Join(
    orders,
    user => user.Id,
    order => order.UserId,
    (user, order) => new { user.Name, order.Amount }
);

8. 常见错误、坑和小技巧

最常见的误区之一:如果你没加.ToList(),结果其实不是列表,而是“延迟查询”(lazy query),只有你第一次遍历时才会真正执行。这很方便,但如果你写完查询后原集合变了,可能会有意外结果。关于“延迟执行”我们后面还会专门聊(等你熟悉LINQ方法后)。

很多新手会搞混,不是所有LINQ方法都能在Query Syntax里用。比如不能直接写select sum(u.Age),得用Method Syntax(users.Sum(u => u.Age))。

2
任务
C# SELF, 第 31 级, 课程 1
已锁定
使用 Query Syntax 进行筛选和排序
使用 Query Syntax 进行筛选和排序
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION