我是否正确使用Automapper 2.0&Incs功能?

时间:2012-01-14 17:31:44

标签: c# automapper automapper-2

我不是,或者它不工作......我有一个Source类,我想要映射到多个彼此继承的视图。

基本类是Detail,子类是Edit或Update,它使用与Detail相同的所有数据,还有几个其他字段来管理自己的列表或其他。

以下是我正在使用的地图:

Mapper.CreateMap<Ticket, Detail>()
                .Include<Ticket, Update>()
                .Include<Ticket, Edit>()
                .ForMember(dest => dest.Priority, opt => opt.MapFrom(src => src.Priority.Code))
                .ForMember(dest => dest.TicketID, opt => opt.MapFrom(src => src.ID))
                .ForMember(dest => dest.Status, opt => opt.MapFrom(src => src.StatusCode))
                .ForMember(dest => dest.Category, opt => opt.MapFrom(src => src.ProblemCategoryCode))
                .ForMember(dest => dest.crmBusCode, opt => opt.MapFrom(src => src.Company.crmBusCode))
                .ForMember(dest => dest.TeamMembers, opt => opt.MapFrom(src => src.Schedules.Where(s => s.CompleteTime == null)));

            Mapper.CreateMap<Ticket, Update>()
                .ForMember(m => m.Schedules, opt => opt.MapFrom(t => t.Schedules.Where(s => s.EmployeeID == Util.CurrentUserID() && s.CompleteTime == null)));

            Mapper.CreateMap<Ticket, Edit>();

然后,如果我在Mapper.Map(ticket)中使用MapFrom的任何属性都没有得到评估,那么如果没有设置映射,它们最终会得到它们已经拥有的值。

那么这里有什么问题?

2 个答案:

答案 0 :(得分:7)

作为替代解决方案,如果您不想两次致电Mapper.Map。您可以将Detail的公共映射移动到扩展方法中:

public static class MappingExtensions
{
    public static IMappingExpression<Ticket, TDest> MapDetailProperties<TDest>(
         this IMappingExpression<Ticket, TDest> mapBase) where TDest : Detail
    {
        return mapBase
            .ForMember(dest => dest.Priority, 
                opt => opt.MapFrom(src => src.Priority.Code))
             ///....
            .ForMember(dest => dest.TeamMembers, 
               opt => opt.MapFrom(src => src
                   .Schedules.Where(s => s.CompleteTime == null)));
    }
}

然后在注册Ticket -> UpdateTicket -> Edit映射器时使用该扩展方法:

Mapper.CreateMap<Ticket, Update>()
    .MapDetailProperties()
    .ForMember(m => m.Schedules, opt => opt.MapFrom(t => t.Schedules
        .Where(s => s.EmployeeID == Util.CurrentUserID() && 
            s.CompleteTime == null)));

Mapper.CreateMap<Ticket, Edit>()
    .MapDetailProperties();

然后你可以正常使用Map:

Ticket ticket = new Ticket();    
var edit = Mapper.Map<Ticket, Edit>(ticket);
var update = Mapper.Map<Ticket, Update>(ticket); 

答案 1 :(得分:5)

  

我是否正确使用Automapper 2.0的Include功能?

否 - 当您使用.Include时,AutoMapper期望目标类与源类处于类似的层次结构中(这将进一步讨论here)。换句话说,如果您要映射到TicketDetailUpdateEdit的不同子类,Include将是合适的。

这对您的情况似乎没有帮助。我建议使用.Map的重载来获取现有对象并对其进行修改。这样,您只需要为基本类型定义映射:

Ticket ticket = new Ticket();
Edit edit = new Edit();

Mapper.Map<Ticket, Detail>(ticket, edit); 
// Edit has now been automapped using the base mapping.

Mapper.Map<Ticket, Edit>(ticket, edit); 
// The properties unique to Edit have now been mapped.