解决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
大体上就是这么个意思了,然后经过测试,在调试模式下,时间节省至2S以内,爽的飞起。
发布完之后,由于源代码与数据库在同一个服务器,访问数据速度更快一些,可以满足使用。