在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
大體上就是這么個意思了,然后經過測試,在調試模式下,時間節省至2S以內,爽的飛起。
發布完之后,由於源代碼與數據庫在同一個服務器,訪問數據速度更快一些,可以滿足使用。