如何映射嵌套类型

时间:2014-12-03 11:07:49

标签: .net automapper

我在做第三级映射时遇到了问题。课程如下:

public class Company {
    public Contact MainContact { get; private set; }
}


public class Contact {
    public PersonsName ContactName { get; private set; }
}

public  class PersonsName  {
    public String FirstName { get; private set; }
    public String LastName { get; private set; }

}

public class CreateCompanyViewModel {
    [Required]
    [MaxLength(25, ErrorMessage = "Only 25 characters are allowed.")]
    [Display(Name = "First Name")]
    public String FirstName { get; set; }

    [Required]
    [MaxLength(25, ErrorMessage = "Only 25 characters are allowed.")]
    [Display(Name = "Last Name")]
    public String LastName { get; set; }
}

我尝试过以下方法但没有成功:

Mapper.CreateMap<CreateCompanyViewModel, PersonsName>()
    .ForMember(dest => dest.FirstName, opt => opt.MapFrom(src => src.FirstName))
    .ForMember(dest => dest.LastName, opt => opt.MapFrom(src => src.LastName));

Mapper.CreateMap<Contact, PersonsName>()
    .ForMember(dest => dest.FirstName, opt => opt.MapFrom(src => src.ContactName.FirstName))
    .ForMember(dest => dest.LastName, opt => opt.MapFrom(src => src.ContactName.LastName));

Mapper.CreateMap<CreateCompanyViewModel, Company>()
    .ForMember(dest => dest.MainContact.ContactName.FirstName, opt => opt.MapFrom(src => src.FirstName))
    .ForMember(dest => dest.MainContact.ContactName.FirstName, opt => opt.MapFrom(src => src.LastName));

我得到的错误信息是:

Expression&#39; dest =&gt; dest.MainContact.ContactName.FirstName&#39;必须解析为顶级成员而不是任何子对象的属性。请在子类型或AfterMap选项上使用自定义解析程序。 参数名称:lambdaExpression

1 个答案:

答案 0 :(得分:2)

您可以使用以下配置:

/* Innermost mapping */
Mapper.CreateMap<CreateCompanyViewModel, PersonsName>();
// You don't need the individual member mappings since the names match.

/* Second-level */
Mapper.CreateMap<CreateCompanyViewModel, Contact>()
    .ForMember(dest => dest.ContactName, opt => opt.MapFrom(src => src));

/* Top level */
Mapper.CreateMap<CreateCompanyViewModel, Company>()
    .ForMember(dest => dest.MainContact, opt => opt.MapFrom(src => src));

这个想法是你使用源类型(CreateCompanyViewModel)作为嵌套类型的源。您可以使用MapFrom(src => src)内的ForMember调用来完成此操作。

示例: https://dotnetfiddle.net/XBJMba

由于src => src位看起来有点奇怪,你可以创建一个扩展方法,让你做得更直接:

public static class AutoMapperExtensions
{
    public static void MapFromSelf<TSourceType>(
        this IMemberConfigurationExpression<TSourceType> expression)
    {
        expression.MapFrom(s => s);
    }
}

用法:

Mapper.CreateMap<CreateCompanyViewModel, Contact>()
    .ForMember(dest => dest.ContactName, opt => opt.MapFromSelf());

Mapper.CreateMap<CreateCompanyViewModel, Company>()
    .ForMember(dest => dest.MainContact, opt => opt.MapFromSelf());