Automapper第一个IQueryable.ProjectTo投影太慢了

时间:2018-02-09 07:30:24

标签: performance entity-framework automapper

我有Dto课程:

public class PackageDto
{
    public MemberDto Receiver { get; set; }
    public MemberDto Sender { get; set; }
    public DocflowDto Docflow { get; set; }

    public DocflowTypeOption DocflowTypeId { get; set; }
    public string Code { get; set; }
    public Guid? DocGuid { get; set; }
}

public class LightPackageDto
{
    public DocflowDto Docflow { get; set; }
    public DocflowTypeOption DocflowTypeId { get; set; }
    public string Code { get; set; }
    public Guid? DocGuid { get; set; }        
}

public class MemberDto
{
    public string Prop1 { get; set; }
    public EntityTypeOption Prop2 { get; set; }
    public string Prop3 { get; set; }
    public string Prop4 { get; set; }
    public string Prop5 { get; set; }
    public PersonDto Director { get; set; }
    public string CompanyShortName { get; set; }
    public string CompanyFullName { get; set; }
    public string CompanyPrefix { get; set; }
}

DocflowDto有3个简单的类型属性,并通过展平进行投影。 PersonDto有3个简单的类型属性,也可以通过展平进行投影

映射规则:

        CreateMap<Person, PersonDto>();
        CreateMap<Member, MemberDto>()
            .ForMember(dest => dest.Prop1, opt => opt.MapFrom(src => src.Employee.Prop1))
            .ForMember(dest => dest.Prop2, opt => opt.MapFrom(src => src.Prop2))
            .ForMember(dest => dest.Prop3, opt => opt.MapFrom(src => src.Employee.Prop3))
            .ForMember(dest => dest.Prop4, opt => opt.MapFrom(src => src.Employee.Prop4))
            .ForMember(dest => dest.Prop5, opt => opt.MapFrom(src => src.Employee.Prop5))
            .ForMember(dest => dest.Director, opt => opt.MapFrom(src => src.Employee.Director))
            .ForMember(dest => dest.CompanyShortName, opt => opt.MapFrom(src => src.Company.CompanyShortName))
            .ForMember(dest => dest.CompanyFullName, opt => opt.MapFrom(src => src.Company.CompanyFullName))
            .ForMember(dest => dest.CompanyPrefix, opt => opt.MapFrom(src => src.Company.Prefix))
            ;
        CreateMap<Data.Models.Docflow.Package, PackageDto>()
            .ForMember(dest => dest.Sender, opt => opt.MapFrom(src => src.Sender))
            .ForMember(dest => dest.Receiver, opt => opt.MapFrom(src => src.Receiver))
            .ForMember(dest => dest.Docflow, opt => opt.MapFrom(src => src.Docflow))
            .ForMember(dest => dest.DocGuid, opt => opt.MapFrom(src => src.Files.FirstOrDefault().DocGuid))
            ;



        CreateMap<Data.Models.Docflow.Package, LightPackageDto>()
            .ForMember(dest => dest.Docflow, opt => opt.MapFrom(src => src.Docflow))
            .ForMember(dest => dest.DocGuid, opt => opt.MapFrom(src => src.Files.FirstOrDefault().DocGuid));

然后测试:

//fast
        var lightEntity = await _db.Packages.Where(p => p.PackageGuid == packageGuid).ProjectTo<LightPackageDto>().FirstOrDefaultAsync();

        //fast (_db.GetPackage make query with all necessary includes)
        var entity = await _db.GetPackage(packageGuid);
        var entityDto = AutoMapper.Mapper.Map<Package, PackageDto>(entity);

        //first run too slow
        var result = await _db.Packages.AsNoTracking().Where(p => p.PackageGuid == packageGuid).ProjectTo<PackageDto>().FirstOrDefaultAsync();

1)因此,如果我投射到LightPackageDto(没有成员投影)就可以了。

2)如果我从包含EF的EF手动返回实体,然后在内存中为#34;做出映射。实体也没关系

3)如果我想要Automapper make&#34;选择&#34;查询应用ProjectTo我总是冻结大约2-3秒。但冻结只出现在第一次。为什么呢?

还有一个问题。我在结果sql select语句中看到所有相关表的所有列。我应该只看到目标投影所需的列。为什么都在那里?

0 个答案:

没有答案