EF Core 查询核心是构建LINQ表达式后由执行方法触发SQL翻译执行。支持条件筛选(Where)、排序(OrderBy)、分页(Skip/Take)、投影(Select)等,且操作均在数据库端完成,未调用ToList()等执行方法前不发送查询。

EF Core 查询数据的核心是通过 DbSet 配合 LINQ 方法构建表达式,最终用执行方法(如 ToList()、FirstOrDefault())触发数据库查询。它不是先加载再筛选,而是把 C# 表达式翻译成 SQL,在数据库端完成过滤、排序、分页等操作。
查全部或单条记录
直接访问 DbSet 属性就能拿到可查询对象:
-
context.Products.ToList():查出所有产品,返回List -
context.Products.First():取第一条,没数据会抛异常 -
context.Products.FirstOrDefault(p => p.Id == 123):按条件找第一个,没匹配则返回null -
context.Products.SingleOrDefault(p => p.Code == "A001"):要求最多一条,多于一条会报错
带条件的筛选查询
用 Where() 添加过滤逻辑,支持链式调用:
context.Orders.Where(o => o.Status == "Shipped" && o.Total > 100)-
context.Users.Where(u => u.Name.Contains("张"))对应 SQL 的LIKE '%张%' -
context.Products.Where(p => new[] {1, 2, 5}.Contains(p.CategoryId))相当于IN子句
排序和分页
排序必须在分页前做,否则结果不可靠:
-
.OrderBy(p => p.Price).ThenByDescending(p => p.Name)支持多级排序 - 分页固定写法:
.Skip((page - 1) * size).Take(size),比如第 3 页、每页 20 条就是Skip(40).Take(20) - 注意:不要在
ToList()之后再Skip/Take,那是在内存里分页,效率极低
只取部分字段或转成匿名/DTO
避免加载整行数据,减少网络和内存开销:
-
context.Products.Select(p => new { p.Name, p.Price })返回匿名类型列表 -
context.Products.Select(p => new ProductSummary { Name = p.Name, Price = p.Price })映射到已有类(需无参构造+可写属性) - 这种投影查询默认不被 EF Core 跟踪,适合只读场景
基本上就这些。实际写的时候记住一点:只要没调执行方法,查询就没发出去;组合好 Where、OrderBy、Select 等都是“描述要什么”,不是“现在就要”。










