Automapper嵌套映射
我读过嵌套的映射wiki页面,但它似乎不喜欢多层次的嵌套。我已经创建了下面的地图并定义了类。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的控制。
它缺少从地址到CompanyInformationDTO
的映射,因为这些对象位于相同的嵌套级别。
该地图为MatchCompanyRequest
- >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
考虑,而不是执行以下操作:
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它会为您解释投影,您可以自定义它以按照您的方式工作。
重要的是你定义了你的导航有多深,以预防*的问题。想象一下这种可能性:
你有2个实体用户和通知在N×N的模式(而 你DTO的对象来表示),当用户自动映射 没有设置MAXDEPTH在你映射器表达,“休斯顿我们有一个 问题”:)。
下面的代码显示了一个workarround来解决所有Mappers的问题。如果你想可以定义到每个映射器。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(对于每个映射)
public class AutoMapperConfig
{
public static void RegisterMappings()
{
Mapper.CreateMap<User, DTOsModel>()
.MaxDepth(1);
}
}
这不是OP的正确答案,但它是非常好的信息。谢谢! – Mathter
谢谢@Mathter! –
怎么会是这样的,如果你不使用静态配置'Mapper'实例? – dougajmcdonald
然后,您只需使用您的实例而不是'AutoMapper.Mapper'?我真的不知道 - 自从我使用AutoMapper以来已经有好几年了...... – Bartosz
是的,现在最好的做法是创建一个配置文件并将其馈送到配置中,以便您可以直接使用而不使用静态实例。我很好奇,因为我认为这是一种常见的解决方案,并想知道它如何适合当前的最佳实践。 – dougajmcdonald