如何在ASP.NET MVC中将SQL Server查询转为EF Lambda写法
Entity Framework 实现NOT IN查询方案
你需要转换的原生SQL逻辑为查询table1中a=1,且b值不在table2里c=1对应的fk_b集合中的所有记录,以下是两种可直接使用的正确EF写法:
写法1:直接映射NOT IN语义的Contains实现
这个写法和原生SQL的NOT IN结构一一对应,注意子查询必须保持IQueryable类型,不要提前执行,否则会触发内存查询:
// 子查询:取出table2中c=1的所有fk_b值,不立即执行 var excludedBs = entity.table2.Where(t => t.c == 1).Select(t => t.fk_b); // 主查询拼接条件 var queryResult = entity.table1 .Where(r => r.a == 1 && !excludedBs.Contains(r.b)) .ToList();
执行时EF会自动将上述语句翻译为和你给出的SQL结构几乎一致的数据库查询,不会把全表数据拉到内存中匹配。
写法2:更稳妥的!Any关联实现
当关联字段允许存null值时,SQL的NOT IN如果子查询结果里出现null,会导致整个查询返回空结果,存在语义坑,用!Any做关联判断可以规避这个问题,且EF翻译出的SQL执行效率通常更高:
var queryResult = entity.table1 .Where(t1 => t1.a == 1 && !entity.table2.Any(t2 => t2.c == 1 && t2.fk_b == t1.b)) .ToList();
这个写法的语义和原SQL完全一致,日常开发优先推荐使用。
注意:不要在子查询上调用
ToList()/AsEnumerable()等立即执行方法,否则会将子查询的所有数据加载到应用内存后再做匹配,数据量大时会出现严重性能问题。
内容的提问来源于stack exchange,提问作者shabnam isfehani
相关产品推荐
相关产品推荐

