必须添加 using system.linq; 才能使用 where、select 等 linq 方法,否则编译报错;from 查询表达式与方法语法等价但适用场景不同;查询变量延迟执行,需 tolist() 等触发;var 推断实际类型,空集合需判空或空合并。

直接用 from 开头写查询表达式,或调用 Where、Select 这类扩展方法,就能查集合——前提是数据源是 IEnumerable<t></t> 或其子类型(比如 List<t></t>、数组),且项目中已引入 System.Linq 命名空间。
必须加 using System.Linq; 才能用 LINQ 方法
没这句,Where、OrderBy、Any 等所有标准查询运算符都不可见。VS 会报错:“'IEnumerable
- 新项目(.NET 6+)可能启用了 implicit usings,
System.Linq会被自动包含,但别依赖它——显式写上更稳妥 - 旧项目或类库中,漏掉这行是新手最常踩的坑,比语法错误还早出现
- 如果用的是 EF Core 的
IQueryable<t></t>,还需额外引用Microsoft.EntityFrameworkCore,但那是另一层逻辑,和内存集合无关
from 查询表达式和方法链语法本质一样,但适用场景不同
编译器会把 from 语法翻译成对应的方法调用,比如 from x in list where x > 5 select x 等价于 list.Where(x => x > 5)。但不是所有操作都能用查询语法写。
- 必须用方法语法的情况:
Count()、First()、Single()、Aggregate()、Except()、Distinct()—— 它们没有对应的from关键字 - 查询语法更适合多步操作:比如先
join再group by最后select new { },可读性明显优于嵌套的.Join(...).GroupBy(...).Select(...) - 匿名类型只能在查询表达式或
Select中用对象初始化器创建,例如select new { Name = c.Name, Len = c.Name.Length }
查询变量是延迟执行的,不遍历就不会真跑
var query = from x in list where x > 10 select x; 这行代码本身不触发任何计算,query 只是一个 IEnumerable<t></t> 对象,记录了“待执行的操作”。真正干活是在 foreach、ToList()、ToArray() 或 Count() 这些地方。
- 重复遍历同一查询变量,每次都会重新执行整个链路(比如重读文件、重查数据库),不是缓存结果
- 想“只算一次”,就用
ToList()或ToArray()立即执行并保存结果 - 如果数据源本身是 EF Core 的
IQueryable<t></t>,延迟执行意味着 SQL 是在最终调用ToList()时才生成并发送到数据库的——这点和内存集合完全不同
常见错误:空引用、类型不匹配、误用 var
var 推断的是实际返回类型,不是“万能类型”。写错会导致编译失败或运行时异常。
-
var result = list.FirstOrDefault(x => x.Id == 5);→ 如果list是List<customer></customer>,result类型就是Customer(可为 null),不是IEnumerable<customer></customer>;后续再调用.Where()就会报错 - 对可能为
null的集合直接写from x in items,运行时抛NullReferenceException—— 必须先判空或用空合并:from x in items ?? Enumerable.Empty<item>()</item> -
string[]和List<string></string>都支持 LINQ,但ArrayList不行(非泛型),得先.Cast<string>()</string>,否则编译不过
真正难的不是语法,而是搞清“这一步到底执行了没”“这个 var 到底是什么类型”“我写的 where 是在内存里筛还是发 SQL 去筛”——这三个问题没理清,LINQ 很容易变成黑盒。










