AutoMapper可以限制映射或映射的深度

时间:2010-08-10 08:57:20

标签: nhibernate lazy-loading automapper

AutoMapper非常棒,节省了大量时间,但当我开始查看应用程序的性能时,AutoMapper负责性能损失。

我正在使用NHibernate进行延迟加载。大多数情况下,需要父实体而根本不需要访问子实体。实际上发生的事情是AutoMapper尝试映射尽可能多的关系,导致NHibernate延迟加载所有子实体(我看到SELECT N + 1一直在发生)。

是否可以限制AutoMapper的深度,或者AutoMapper是否可以懒惰地映射子实体?

3 个答案:

答案 0 :(得分:5)

您可以将ignore方法用于不需要加载的关联。

Mapper.CreateMap<User, UserDto>()
    .ForMember(dest => dest.LazyCollection, opt => opt.Ignore())
    .ForMember(dest => dest.AnotherLazyCollection, opt => opt.Ignore())
Mapper.CreateMap<UserProperty, UserPropertyDto>()
    .ForMember(dest => dest.PropertyLazyReference, opt => opt.Ignore());
return Mapper.Map<User, UserDto>(user);

对于您知道在dto中需要的关联,您应该查看使用初始查询更有效地获取这些关联的方法,但这是一个全新的问题。

答案 1 :(得分:0)

也许你应该考虑使用两种不同的dtos;一个包含子实体,一个不包含子实体。然后,您可以根据上下文从服务层返回正确的dto。

答案 2 :(得分:0)

我正在使用前提条件来防止数据被映射。

CreateMap<Team, TeamDto>()
    .ForMember(dto => dto.Users, options =>
    {
        options.PreCondition(ctx => !ctx.Items.ContainsKey(AutoMapperItemKeys.SKIP_TEAM_USERS));
        options.MapFrom(t => t.TeamUsers.Where(tu => tu.IsDeleted == false));
    })
    .ReverseMap();

调用Map()时,我向Items字典提供了我不想映射的属性的跳过键。

this.mapper.Map<IEnumerable<Team>, IEnumerable<TeamDto>>(teams, opts =>
{
    opts.Items.Add(AutoMapperItemKeys.SKIP_TEAM_USERS, true);
});

优势:

  • 您可以细化哪些属性无法映射
  • 防止使用嵌套对象映射到深层
  • 不需要重复的dto
  • 没有重复的映射配置文件