【问题标题】:Am I using Automapper 2.0's Include functionality correctly?我是否正确使用 Automapper 2.0 的包含功能?
【发布时间】:2012-02-10 10:44:10
【问题描述】:

要么我不是,要么它不工作......我有一个 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 的属性都没有得到评估,它们最终会得到没有设置映射时它们应该拥有的值。

那么这里出了什么问题?

【问题讨论】:

  • 您使用的是哪个 Automapper 版本?

标签: c# automapper automapper-2


【解决方案1】:

如果您不想拨打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 -&gt; UpdateTicket -&gt; 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); 

【讨论】:

  • 多一点工作,但似乎绝对是正确的方法!我是唯一一个认为 Include 基本上像这种扩展方法那样更有意义的人吗?
  • 我的类似问题的解决方案与此略有不同,但它使用了静态扩展方法的核心概念。我希望 AutoMapper 能够开箱即用地支持这一点,并希望他们将来会支持。
【解决方案2】:

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

否--当您使用.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.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2018-09-28
    • 2012-10-07
    相关资源
    最近更新 更多