Entity Framework Core的坑:Skip/Take放在Select之前造成Include的實體全表查詢


今天將一個遷移至 ASP.NET Core 的項目放到一台 Linux 服務器上試運行。站點啟動后,瀏覽器打開一個頁面一直處於等待狀態。接着奇怪的事情發生了,整個 Linux 服務器響應緩慢,ssh命令行輸入都一頓一頓的,過了一會,直接停止響應,down機了,必須強制重啟服務器才行。再啟動站點,再訪問,問題依舊。換一台服務器,down機依然。

排查時在日志中發現了這樣的報警:

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 怎么就變卦了呢?

后來在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 的報警信息。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM