1. 程式人生 > >解決EF 迴圈操作、遍歷導致操作變慢,等待時間過長的問題,EF關聯查詢

解決EF 迴圈操作、遍歷導致操作變慢,等待時間過長的問題,EF關聯查詢

在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以內,爽的飛起。
釋出完之後,由於原始碼與資料庫在同一個伺服器,訪問資料速度更快一些,可以滿足使用。