EF中DbSet.Where为何先查询全表而非按过滤条件筛选?
问题原因与解决方案
为啥会查全表?
你这里用的Func<TEntity, bool>是个委托类型,EF遇到这种参数的Where方法时,会直接触发客户端求值逻辑:先把整张表的所有数据都拉到本地内存,再用这个委托在内存里过滤符合条件的记录。这就是日志里显示查全表的根本原因。
怎么改成数据库端过滤?
把参数类型换成Expression<Func<TEntity, bool>>——这是表达式树类型,EF能把它翻译成对应的SQL语句,让数据库先执行过滤,只返回符合条件的数据,不会拉全表。
修改后的代码:
void Function(Expression<Func<TEntity, bool>> where) { var objects = DbSet.Where(where); foreach(var obj in objects) DbSet.Remove(obj); }
额外说明
- 如果你的过滤逻辑里有只能在本地内存执行的复杂操作(比如调用本地自定义方法),那只能用
Func委托做客户端过滤,但这种场景要尽量避免,毕竟拉全表性能太差。 - 另外,
DbSet本身就是IQueryable类型,不需要额外调用AsQueryable(),属于多余操作。
内容的提问来源于stack exchange,提问作者TechieNoob
相关产品推荐
相关产品推荐

