我在服务层启用了延迟加载的对象到对象映射代码(使用automapper):
public IEnumerable<TaskViewModel> MapToView(IEnumerable<IRAS_PM_TaskAssignment> models)
{
Mapper.CreateMap<IRAS_PM_TaskAssignment, TaskViewModel>()
.ForMember(t => t.AssetOrShotName, map => map.MapFrom(t => t.IRAS_PM_Asset_Sequence.AssetShotName))
.ForMember(t => t.Days, map => map.MapFrom(t => (t.StartDate.HasValue && t.DeadLine.HasValue)
? t.DeadLine.Value.Subtract(t.StartDate.Value).TotalDays
: 0.0))
.ForMember(t => t.DepartmentName, map => map.MapFrom(t => t.IRAS_PM_DepartmentName.DeptName));
return models.Select(x => Mapper.Map<IRAS_PM_TaskAssignment, TaskViewModel>(x));
}
我的控制器电话是:
public ActionResult TaskRead([DataSourceRequest] DataSourceRequest request, int? projectId)
{
var tasks = projectId.HasValue
? _taskRepository.MapToView(_taskRepository.FindBy(x => x.ProjectId == projectId).ToList())
: _taskRepository.MapToView(_taskRepository.All.ToList());
return Json(tasks.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
在检查EF查询时,miniprofiler警告我重复阅读器查询:
我做错了什么?请帮我删除多余的读者。
答案 0 :(得分:1)
问题出在这一行:
.ForMember(t => t.DepartmentName, map => map.MapFrom(t => t.IRAS_PM_DepartmentName.DeptName));
对于此处的每个IRAS_PM_TaskAssignment
实体,您正在加载查找与该实体相关的IRAS_PM_DepartmentName
,并获取其部门名称。
由于延迟加载,对于您要加载的每一行,都会一次调用一个。
解决方案是在IRAS_PM_DepartmentName
与您的基地IRAS_PM_TaskAssignment
相关的实体上执行eager loading。执行此操作的代码将删除此内容:
_taskRepository.FindBy(x => x.ProjectId == projectId).ToList();
而是使用这样的东西:
_taskRepository.FindBy(x => x.ProjectId == projectId)
.Include(x => x.IRAS_PM_TaskAssignment)
.ToList();
您可以对未经过滤的检索进行类似的更改。
Include
语句应该在初始查询中删除每个相关项目,从而无需随后查看每个项目,一次一个。