今天将一个迁移至 ASP.NET Core 的项目放到一台 Linux 服务器上试运行。站点启动后,浏览器打开一个页面一直处于等待状态。接着奇怪的事情发生了,整个 Linux 服务器响应缓慢,ssh命令行输入都一顿一顿的,过了一会,直接中止响应,down机了,必须强制重启服务器才行。再启动站点,再访问,问题依旧。换一台服务器,down机依然。git
排查时在日志中发现了这样的报警:github
warn: Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryCompilationContextFactory[8] The LINQ expression 'xxx' could not be translated and will be evaluated locally.
而后用 SQL Profiler 跟踪了一下 EF Core 生成的 SQL 语句,发现了一条全表查询的SQL语句,而这张表有80多万条数据。罪魁祸首就是它,在内存中加载80多万条数据进行查询,结果把只有1核1G的Linux服务器搞挂了。数据库
这个项目以前用的是基于 .NET Framework 的 Entity Framework ,并无出现这个问题。换成 Entity Framewor Core 怎么就变卦了呢?express
后来在GitHub上发现了线索 —— The LINQ expression could not be translated and will be evaluated locally wrong warning:浏览器
If possible, you should always try to put Skip/Take/Distinct as the last operation when using EF Core (at least until we address the current limitations).
在咱们这个项目中的确存在将 Skip/Take 放在 Select 以前的 LINQ 查询代码,修改以后问题立马解决。而发生全表查询的数据库表所对应的实体,是在 LINQ 中 Include 进来的(Eager loading)。服务器
这是目前版本的 EF Core 的一个坑,使用时需注意。建议使用 EF Core 时,必定要看日志中 EF Core 的报警信息。 ssh