解決EF 迴圈操作、遍歷導致操作變慢,等待時間過長的問題,EF關聯查詢
阿新 • • 發佈:2020-03-25
在EF與資料庫進行操作時,經常會出現遍歷操作資料庫的場景
var taskFormList = _context.TaskForms.Where(m => m.NoticeDate >= today).ToList();
foreach (var taskform in taskFormList) { var assign = _context.LTFAssigns.Where(m => m.TaskFormID == taskform.ID).ToList(); foreach (var item in assign) { assignsList.Add(item); } }
在上述程式碼中,假如taskFormList 數量上萬條的資料時,電腦就會一直卡在這個地方,實際除錯時,數量400條,電腦操作了2.5min。
一、什麼原因造成的卡頓?
首先來看一下 程式碼的執行流程
遍歷taskFormList ,然後taskFormList 裡的每一項都會執行
var assign = _context.LTFAssigns.Where(m => m.TaskFormID == taskform.ID).ToList();
也就意味著要訪問一次資料庫,而資料庫的訪問流程是要先開啟一個事務,執行查詢操作,然後關閉事務,並將獲取的資料寫入記憶體
taskFormList 400條資料 意味著400次上述操作
taskFormList 10000條資料 意味著10000次上述操作
這就是造成等待時間的主要原因。
二、那麼如何解決呢
如果可以在資料庫裡直接把上述操作完成,然後程式訪問一次資料庫,直接獲取結果存到記憶體就好了,這是理想的結果。
方法一:
直接寫SQL語句的關聯查詢,然後用ado.net 進行查詢
但是我們用的是EF,那麼有沒有用EF的關聯查詢呢
也有一種辦法。
方法二:
直接上程式碼吧
var assignsList = _context.LTFAssigns.Join(_context.TaskForms.Where(m=>m.NoticeDate>=today), e => e.TaskFormID, o => o.ID, (e, o) => new { e.ID ,e.TaskFormID,e.DepartmentID,e.DepartmentName,e.AssignTime,e.UsedTime,e.TaskFormState,e.AssignedTimes,e.FinishedTimes}).ToList();
這個就是關聯查詢了
自己對照著SQL語句 就知道大概意思了
select e.ID ,e.TaskFormID,e.DepartmentID,e.DepartmentName,e.AssignTime,e.UsedTime,e.TaskFormState,e.AssignedTimes,e.FinishedTimes from LTFAssigns e left join TaskForms o on e.TaskFormID=o.ID
where o.NoticeDate>=today
大體上就是這麼個意思了
然後經過測試,在除錯模式下,時間節省至2 S以內,爽的飛起。
釋出完之後,由於原始碼與資料庫在同一個伺服器,訪問資料速度更快一些,可以滿足使用。