自动映射嵌套映射

时间:2011-10-24 14:02:07

标签: c# automapper

我已经阅读了嵌套映射维基页面,但似乎不喜欢多层嵌套。我已经创建了以下地图并定义了类。

AutoMapper.Mapper.CreateMap<Address, AddressDTO>();
AutoMapper.Mapper.CreateMap<MatchCompanyRequest, MatchCompanyRequestDTO>();

public class MatchCompanyRequest
{
    Address Address {get;set;}
}

public class MatchCompanyRequestDTO
{
    public CompanyInformationDTO {get;set;}
}

public class CompanyInformationDTO {get;set;}
{
    public string CompanyName {get;set;}
    public AddressDTO Address {get;set;}
}

但是以下代码......

// works
matchCompanyRequestDTO.companyInformationDTO.Address =
    AutoMapper.Mapper.Map<Address, AddressDTO>(matchCompanyRequest.Address);

// fails
matchCompanyRequestDTO =
    AutoMapper.Mapper
        .Map<MatchCompanyRequest, MatchCompanyRequestDTO>(matchCompanyRequest);

这种深度嵌套是否有效并且我配置不正确?或者这种嵌套还没有得到支持?

- 编辑

对于任何有兴趣的人,我都无法控制DTO。

3 个答案:

答案 0 :(得分:6)

它缺少从Address到CompanyInformationDTO的映射,因为这些对象位于同一个嵌套级别。

MatchCompanyRequest创建地图 - &gt; MatchCompanyRequestDTO,但无法确定是否可以将Address映射到CompanyInformationDTO

因此,您的MatchCompanyRequestDTO实际上可能与您的CompanyInformationDTO具有相同的声明:

public class MatchCompanyRequestDTO
{
    public string CompanyName {get;set;}
    public AddressDTO Address {get;set;}
}

如果您想使用自动映射,这当然只会影响您。您仍然可以手动配置您的地图,但似乎应修复DTO,让我们尝试:

public class CustomResolver : ValueResolver<Address, CompanyInformationDTO>
{
    protected override CompanyInformationDTO ResolveCore(Address source)
    {
        return new CompanyInformationDTO() { Address = Mapper.Map<Address, AddressDTO>(source) };
    }
}
// ...

AutoMapper.Mapper.CreateMap<MatchCompanyRequest, MatchCompanyRequestDTO>()
    .ForMember(dest => dest.companyInformationDTO, opt => opt.ResolveUsing<CustomResolver>().FromMember(src => src.Address)); // here we are telling to use our custom resolver that converts Address into CompanyInformationDTO

答案 1 :(得分:5)

重要的是你要定义导航的深度,以克服堆栈溢出问题。想象一下这种可能性:

  

您在NxN模型中有2个实体用户通知(和   当你使用自动映射器时,你有DTOs对象来表示)   没有在映射器表达式中设置 MaxDepth ,&#34;休斯顿我们有一个   问题&#34; :)

下面的代码显示了为所有Mappers解决此问题的解决方法。如果你想要可以定义到每个mapper。 Like this Question

解决方案1(全球定义)

public class AutoMapperConfig
{
    public static void RegisterMappings()
    {
        Mapper.Initialize(mapperConfiguration =>
        {
            mapperConfiguration.AddProfile<DomainModelToYourDTOsMappingProfile>();
            mapperConfiguration.AddProfile<YourDTOsToDomainModelMappingProfile>();
            mapperConfiguration.AllowNullCollections = true;
            mapperConfiguration.ForAllMaps(
                (mapType, mapperExpression) => {
                    mapperExpression.MaxDepth(1);
                });
        }
    }

解决方案2(对于每个Mapper)

 public class AutoMapperConfig
 {
     public static void RegisterMappings()
     {
         Mapper.CreateMap<User, DTOsModel>()
               .MaxDepth(1);
     }
 }

答案 2 :(得分:0)

请考虑以下内容:

public class MatchCompanyRequest
{
    Address Address {get;set;}
}

public class MatchCompanyRequestDTO
{
    public string Name {get;set;}
    public AddressDTO Address {get;set;}
}

public class AddressDTO
{
    ....
}

您的DTO对象需要与域对象具有相同的结构,以便在AutoMapper中使用默认的映射约定。

看看这个:https://github.com/AutoMapper/AutoMapper/wiki/Projection它会为你解释投影,你可以按照你的方式自定义投影。