EF Core:查看生成SQL并修改IQueryable查询添加过滤与关联
Entity Framework Core 实用技巧:查看生成SQL与优化IQueryable查询
一、查看EF Core生成的SQL代码
- 用LogTo实时输出(EF Core 5及以上):在DbContext的
OnConfiguring方法里加一行配置,就能把执行的SQL直接输出到控制台:optionsBuilder.LogTo(Console.WriteLine, new[] { DbLoggerCategory.Database.Command.Name }); - 用ToQueryString()获取单个查询的SQL:直接给你的IQueryable对象调用这个方法,就能拿到对应的SQL字符串,调试单个查询很方便:
var userQuery = dbContext.Users.Where(u => u.Age > 18); string sql = userQuery.ToQueryString(); - 用SQL Server Profiler(针对SQL Server):如果你的数据库是SQL Server,打开Profiler跟踪数据库请求,能看到EF Core实际发送的SQL语句。
- 第三方工具辅助:比如EF Core Profiler这类工具,不过前面几种原生方法足够应付大部分场景。
二、修改IQueryable查询:加过滤、关联表过滤但不选关联列
1. 添加额外过滤条件
直接链式调用Where就行,比如先筛选活跃用户,再加时间范围过滤:
var query = dbContext.Users.Where(u => u.IsActive); // 追加过滤条件 query = query.Where(u => u.CreatedDate >= DateTime.Now.AddMonths(-6));
2. 关联表用于过滤(不返回关联列)
有两种常用方式,都不会把关联表的列选出来:
- 用Where+Any/All:如果模型里已经配置了导航属性,直接通过导航属性判断就行,EF Core会自动生成JOIN语句,但只返回主表数据:
// 筛选出有未完成订单的用户,只返回User的列 var query = dbContext.Users .Where(u => u.Orders.Any(o => o.Status == OrderStatus.Uncompleted)); - 手动Join+过滤+选主表:如果没配置导航属性,手动Join后过滤,最后Select回主表实体:
var query = dbContext.Users .Join(dbContext.Orders, u => u.Id, o => o.UserId, (u, o) => new { User = u, Order = o }) .Where(uo => uo.Order.Status == OrderStatus.Uncompleted) .Select(uo => uo.User);
不管哪种方式,EF Core都会自动优化SQL,不会多余选择关联表的列,只要你最终只选择主表的内容就行。
内容的提问来源于stack exchange,提问作者Amirreza Taleb
相关产品推荐
相关产品推荐

