EF Core 6中如何将内连接SQL转换为LINQ(不使用FromSqlRaw)
.NET Core 6 无FromSqlRaw的LINQ实现方案
以下实现基于EF Core,假设DbContext中已注册对应两个实体的DbSet,属性名采用C#大驼峰命名规范,和数据库表字段按默认规则映射。
写法1:手动指定内连接(不依赖导航属性配置,和原始SQL逻辑完全一一对应)
// 替换为实际传入的cltID、facID参数 int cltId = 1; int facId = 1; var triggerList = await ( from cft in _dbContext.ClientFacilityTriggers join trg in _dbContext.Triggers on cft.TrgId equals trg.TrgId where cft.CltId == cltId && cft.FacId == facId select new Triggers { TrgId = trg.TrgId, AtvId = trg.AtvId, TrgEvent = trg.TrgEvent, TrgIsDeleted = trg.TrgIsDeleted } ).ToListAsync();
写法2:基于导航属性的简化写法(如果实体已配置关联导航)
如果你的ClientFacilityTriggers实体中配置了指向Triggers的导航属性,EF Core会自动生成对应INNER JOIN逻辑,不需要手动写join语句:
int cltId = 1; int facId = 1; var triggerList = await _dbContext.ClientFacilityTriggers .Where(cft => cft.CltId == cltId && cft.FacId == facId) .Select(cft => cft.Triggers) .ToListAsync();
注意:如果导航属性配置为可空引用,生成的SQL会是LEFT JOIN,需要额外加非空判断才会生成INNER JOIN。
SQL转LINQ的通用转换思路
- 第一步拆解SQL结构:先把SQL拆成
数据源关联、筛选条件、返回字段三个核心部分,不要上来就写全句。 - 对应关联逻辑:SQL里的INNER JOIN对应LINQ的
join 关联表 on 主表关联字段 equals 关联表关联字段语法,注意equals两边字段顺序必须和join的两个表顺序一致,写反会编译报错。 - 对应筛选逻辑:SQL里WHERE后的判断条件直接平移到LINQ的
where子句即可,注意C#中相等判断用双等号==,不要用SQL里的单等号。 - 对应返回逻辑:SQL SELECT后需要的字段,在LINQ的
select子句里做映射即可,如果要返回完整关联表实体,直接映射对应实体对象即可,不需要逐字段赋值。
非官方、非自动转换工具的学习资源推荐
- 找《LINQ实战》的实体书或者社区整理的核心章节笔记,这本书会从LINQ的底层执行逻辑、委托和Lambda与LINQ的关系讲起,不是零散的语法堆砌,看完能理解不同LINQ写法为什么会生成对应的SQL。
- 做反向对照练习:打开EF Core的SQL日志输出,自己写不同场景的LINQ查询,对照生成的SQL和自己预期的差异,重点练连接、分组、聚合、子查询四类场景,练10-20个场景就能摸透对应规律,比死记转换规则效率高很多。
- 阅读成熟开源项目的EF Core数据访问层代码,看实际生产环境中复杂查询的写法,能避开很多新手常见坑,比如客户端评估、连接条件错误、分页逻辑错误等。
内容的提问来源于stack exchange,提问作者Rob
相关产品推荐
相关产品推荐

