使用EF 5的Miniprofiler检查重复查询(读者)

时间:2013-10-02 05:09:53

标签: c# entity-framework asp.net-mvc-4 automapper

我在服务层启用了延迟加载的对象到对象映射代码(使用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 alert

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

1 个答案:

答案 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语句应该在初始查询中删除每个相关项目,从而无需随后查看每个项目,一次一个。