1

我在启用延迟加载的服务层中有我的对象到对象映射代码(使用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 警告我重复的阅读器查询: Miniprofiler 警报

我究竟做错了什么?请帮我删除多余的读者。

4

1 回答 1

1

问题出在这一行:

.ForMember(t => t.DepartmentName, map => map.MapFrom(t => t.IRAS_PM_DepartmentName.DeptName)); 

对于此处的每个IRAS_PM_TaskAssignment实体,您正在加载查找IRAS_PM_DepartmentName与该实体相关的内容,并获取其部门名称。

由于延迟加载,对于您正在加载的每一行,它们一次调用一个。

解决方案是在与您的 base 相关的实体上执行预加载。执行此操作的代码将其删除:IRAS_PM_DepartmentNameIRAS_PM_TaskAssignment

_taskRepository.FindBy(x => x.ProjectId == projectId).ToList();

而是使用这样的东西:

_taskRepository.FindBy(x => x.ProjectId == projectId)
               .Include(x => x.IRAS_PM_TaskAssignment)
               .ToList();

您可以对未过滤的检索进行类似的更改。

Include语句应在初始查询中下拉每个相关项目,从而无需随后逐个查找,一次一个。

于 2013-10-02T05:30:45.077 回答