C# 自动映射嵌套映射
我已经阅读了嵌套映射wiki页面,但它似乎不喜欢多层嵌套。我已经创建了以下映射并定义了类C# 自动映射嵌套映射,c#,automapper,C#,Automapper,我已经阅读了嵌套映射wiki页面,但它似乎不喜欢多层嵌套。我已经创建了以下映射并定义了类 AutoMapper.Mapper.CreateMap<Address, AddressDTO>(); AutoMapper.Mapper.CreateMap<MatchCompanyRequest, MatchCompanyRequestDTO>(); public class MatchCompanyRequest { Address Address {get;set;
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;}
}
AutoMapper.Mapper.CreateMap();
AutoMapper.Mapper.CreateMap();
公共类MatchCompanyRequest
{
地址{get;set;}
}
公共类MatchCompanyRequestTo
{
上市公司信息数据{get;set;}
}
公共类CompanyInformation数据到{get;set;}
{
公共字符串CompanyName{get;set;}
公共地址到地址{get;set;}
}
但是下面的代码
// works
matchCompanyRequestDTO.companyInformationDTO.Address =
AutoMapper.Mapper.Map<Address, AddressDTO>(matchCompanyRequest.Address);
// fails
matchCompanyRequestDTO =
AutoMapper.Mapper
.Map<MatchCompanyRequest, MatchCompanyRequestDTO>(matchCompanyRequest);
//有效
匹配companyrequestdto.companyInformationDTO.Address=
AutoMapper.Mapper.Map(匹配公司请求地址);
//失败
匹配公司请求=
自动映射器
.Map(匹配公司请求);
这种深嵌套是否有效,我是否配置不当?还是这种嵌套还不受支持
--编辑
对任何感兴趣的人来说,我不是DTO的控制者 它缺少从地址到公司信息数据到的映射,因为这些对象位于同一嵌套级别 该映射是为
MatchCompanyRequest
->MatchCompanyRequestDTO
创建的,但它无法确定是否可以将地址
映射到公司信息dto
因此,您的匹配公司请求to
实际上可以与您的公司信息dto
具有相同的声明:
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
公共类CustomResolver:ValueResolver
{
受保护的覆盖公司信息数据到ResolveCore(地址源)
{
返回新的CompanyInformationDTO(){Address=Mapper.Map(source)};
}
}
// ...
AutoMapper.Mapper.CreateMap()
.FormMember(dest=>dest.companyInformationDTO,opt=>opt.resolvesusing().FromMember(src=>src.Address));//在这里,我们告诉您使用我们的自定义解析器,将地址转换为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中工作
看看这个:它将为您解释投影,您可以自定义它,使其按您现有的方式工作。重要的是您定义导航的深度,以避免堆栈溢出问题。想象一下这种可能性: NxN模型中有两个实体用户和通知(和 当您使用自动映射器时,您有DTOs对象来表示它) 如果没有设置MaxDepth,在映射器表达式中,“Houston,我们有一个 问题“:”) 下面的代码显示了一个解决所有映射器此问题的解决方法。如果需要,可以为每个映射器定义 解决方案1(全局定义)
public类AutoMapperConfig
{
公共静态无效注册表映射()
{
初始化(mapperConfiguration=>
{
mapperConfiguration.AddProfile();
mapperConfiguration.AddProfile();
mapperConfiguration.AllowNullCollections=true;
mapperConfiguration.ForAllMaps(
(mapType,mapperExpression)=>{
maxperexpression.MaxDepth(1);
});
}
}
解决方案2(针对每个映射器)
public类AutoMapperConfig
{
公共静态无效注册表映射()
{
Mapper.CreateMap()
.MaxDepth(1);
}
}
这不是OP的正确答案,但它确实是很好的信息。谢谢!谢谢@matter!如果您不使用静态映射器
实例,那么如何配置类似的内容?那么您只需使用您的实例而不是AutoMapper.Mapper
?我真的不知道-我已经使用AutoMapper多年了…耶啊,现在的最佳实践是创建一个配置文件并将其输入配置中,这样您就可以对其进行DI,而不必使用静态实例。我很好奇,因为我认为这是一个常见的解决方案,并且想知道它如何与当前的最佳实践相适应。但为什么会有所不同呢?您可以在注入的实例上调用CreateMap
,然后使用rest同样的…您在注入的实例上没有CreateMap
,而是创建一个配置文件,并在其中调用CreateMap
,因为它继承自profile
。在解析器中,您无权访问注入的实例。
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);
});
}
}
public class AutoMapperConfig
{
public static void RegisterMappings()
{
Mapper.CreateMap<User, DTOsModel>()
.MaxDepth(1);
}
}