-
LINQ基础:查询语法与方法语法
LINQ基础:查询语法与方法语法
-
LINQ概述
LINQ(Language Integrated Query)是C#内置的查vb.net教程C#教程python教程SQL教程access 2010教程询技术,它统一了对集合、数据库、XML等多种数据源的查询方式,核心优势:
语法一致:用相同的语法查询不同类型的数据源;
类型安全:编译时检查查询错误;
可读性高:接近自然语言或SQL语法;
灵活高效:支持延迟执行和链式调用。
LINQ有两种主要语法:查询语法(类似SQL)和方法语法(基于扩展方法+Lambda)。 -
查询语法(Query Syntax)
查询语法采用声明式风格,用from、where、orderby、select等关键字,结构类似SQL。
2.1 实例代码:筛选用户
csharp
using System;
using System.Collections.Generic;
using System.Linq;
// 定义用户类
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
class Program
{
static void Main()
{
// 数据源:用户列表
List<User> users = new List<User>
{
new User { Id = 1, Name = "张三", Age = 28 },
new User { Id = 2, Name = "李四", Age = 22 },
new User { Id = 3, Name = "王五", Age = 30 },
new User { Id = 4, Name = "赵六", Age = 25 }
};
// 1. 查询语法:筛选年龄>25的用户,按年龄升序排列,取Name和Age
var query = from u in users // 指定数据源(u为迭代变量)
where u.Age > 25 // 筛选条件
orderby u.Age ascending // 排序(ascending可省略)
select new { u.Name, u.Age }; // 投影:只取Name和Age(匿名类型)
// 2. 执行查询并输出结果
Console.WriteLine("查询语法结果:");
foreach (var user in query)
{
Console.WriteLine($"姓名:{user.Name},年龄:{user.Age}");
}
}
}
2.2 逐行讲解
数据源:List
查询语句:
ofrom u in users:指定数据源为users,u是每个元素的别名;
owhere u.Age>25:筛选条件(只保留年龄>25的用户);
oorderby u.Age:按年龄升序排序(descending表示降序);
oselect new {u.Name, u.Age}:投影操作,创建匿名类型,只包含需要的属性;
执行查询:foreach遍历查询结果时,LINQ才会真正执行查询(延迟执行)。
输出结果:
查询语法结果:
姓名:张三,年龄:28
姓名:王五,年龄:30
-
方法语法(Method Syntax)
方法语法采用命令式风格,通过扩展方法(如Where、OrderBy)和Lambda表达式实现查询,更灵活。
3.1 实例代码:对应查询语法的例子
csharp
// 替换Main方法中的查询语句:用方法语法实现相同逻辑
var methodQuery = users
.Where(u => u.Age >25) // 筛选:Lambda表达式指定条件
.OrderBy(u => u.Age) // 排序:按年龄升序
.Select(u => new { u.Name, u.Age }); // 投影:匿名类型
// 输出结果
Console.WriteLine("
方法语法结果:");
foreach (var user in methodQuery)
{
Console.WriteLine($"姓名:{user.Name},年龄:{user.Age}");
}
3.2 逐行讲解
扩展方法:Where、OrderBy、Select是IEnumerable
Lambda表达式:u => u.Age>25表示“输入用户u,返回u.Age>25的布尔值”;
链式调用:方法语法支持链式调用,每个方法返回新的IEnumerable
延迟执行:与查询语法相同,直到遍历或调用ToList()/ToArray()才执行。
输出结果与查询语法一致。
4. 查询语法vs方法语法:对比
| 特性 | 查询语法(Query Syntax) | 方法语法(Method Syntax) |
|---|---|---|
| 语法风格 | 声明式(类似SQL) | 命令式(扩展方法+Lambda) |
| 适用场景 | 简单查询(筛选、排序、投影) | 复杂查询(链式调用、聚合、分组) |
| 可读性 | 对SQL熟悉者更易读 | 对Lambda熟悉者更易读 |
| 灵活性 | 有限(不支持所有LINQ操作符) | 高(支持所有LINQ操作符) |
| 编译结果 | 编译为方法语法的IL代码 | 直接编译为IL代码 |
注意:查询语法是方法语法的“语法糖”,编译器会自动将查询语法转换为方法语法。
5. 基础知识拓展
5.1 延迟执行vs立即执行
延迟执行:查询语句定义时不执行,直到遍历或调用GetEnumerator()才执行(如foreach)。优点:节省内存,支持动态数据源更新。
o延迟执行的方法:Where、OrderBy、Select等;
立即执行:调用方法时立即执行查询,返回结果集(如List
o立即执行的方法:ToList()、ToArray()、Count()、Sum()等。
例子:
csharp
// 延迟执行:未实际查询
var delayedQuery = users.Where(u => u.Age>25);
users.Add(new User { Id=5, Name="钱七", Age=29 }); // 修改数据源
var result = delayedQuery.ToList(); // 立即执行:包含新添加的钱七
5.2 常见LINQ操作符
| 类别 | 操作符示例 | 作用说明 |
|---|---|---|
| 过滤 | Where、OfType | 筛选符合条件的元素 |
| 排序 | OrderBy、ThenBy、Reverse | 对元素排序 |
| 投影 | Select、SelectMany | 转换元素类型或提取属性 |
| 聚合 | Count、Sum、Average、Max | 计算集合的统计值 |
| 集合 | Distinct、Union、Intersect | 处理集合的交集、并集等 |
| 分组 | GroupBy | 按指定键分组元素 |
5.3 多数据源支持
LINQ可查询多种数据源:
集合:List
数据库:通过EF Core(LINQ to Entities);
XML:LINQ to XML;
JSON:结合第三方库(如Newtonsoft.Json)实现。
6. 总结与练习
6.1 总结
LINQ统一了多种数据源的查询方式;
查询语法:声明式,类似SQL,适合简单查询;
方法语法:命令式,灵活,支持链式调用;
延迟执行是LINQ的核心特性,节省资源。
6.2 练习
实现以下功能(用两种语法):
1.数据源:List
2.查询条件:价格>100元的产品;
3.排序:按价格降序排列;
4.结果:取前3个产品的Name和Price。
参考代码(方法语法):
csharp
List<Product> products = new List<Product>
{
new Product { Id=1, Name="手机", Price=2999 },
new Product { Id=2, Name="耳机", Price=199 },
new Product { Id=3, Name="电脑", Price=5999 },
new Product { Id=4, Name="键盘", Price=99 },
new Product { Id=5, Name="鼠标", Price=129 }
};
var result = products
.Where(p => p.Price>100)
.OrderByDescending(p => p.Price)
.Take(3) // 取前3个
.Select(p => new { p.Name, p.Price });
(本节完)
下一章:LINQ进阶:分组、聚合与连接查询
(深入讲解GroupBy、Join等复杂LINQ操作)
本站原创,转载请注明出处:https://www.xin3721.com/ArticlecSharp/c49377.html










