简体   繁体   English

自动映射嵌套映射

[英]Automapper nested mapping

I've read the nested mapping wiki page but it appears to not like multiple levels of nesting. 我已经阅读了嵌套映射维基页面,但似乎不喜欢多层嵌套。 I've got the following maps created and classes defined. 我已经创建了以下地图并定义了类。

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;}
}

But the following code... 但是以下代码......

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

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

Does this deep nesting work and I have it configured improperly? 这种深度嵌套是否有效,而且我的配置不正确? Or is this kind of nesting not yet supported? 或者这种嵌套还没有得到支持?

-- Edit - 编辑

For anyone interested, I am not in control of the DTOs. 对于任何有兴趣的人,我都无法控制DTO。

It lacks the mapping from Address to CompanyInformationDTO , as those objects are on the same nest-level. 它缺少从Address到CompanyInformationDTO的映射,因为这些对象位于同一个嵌套级别。

The map is created for MatchCompanyRequest -> MatchCompanyRequestDTO , but it is unable to figure out whether it can map Address to CompanyInformationDTO . 该地图是为MatchCompanyRequest - > MatchCompanyRequestDTO创建的,但无法确定它是否可以将Address映射到CompanyInformationDTO

So your MatchCompanyRequestDTO could in fact have same declaration as your CompanyInformationDTO : 因此,您的MatchCompanyRequestDTO实际上可能与您的CompanyInformationDTO具有相同的声明:

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

This of course only affects you if you want to use automatic mapping. 如果您想使用自动映射,这当然只会影响您。 You still can configure your maps manually, but it seems like the DTOs should be fixed instead, let's try anyway: 您仍然可以手动配置您的地图,但似乎应该修复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

The important thing is you define how deeper is your navigation, to previne the stackoverflow problems. 重要的是你定义导航的深度,以解决堆栈溢出问题。 Imagine this possibility: 想象一下这种可能性:

You have 2 entities Users and Notifications in NxN model (And you have DTOs object to represent that), when you user auto mapper without set MaxDepth in you mapper expression, "Houston we have a problem" :). 您在NxN模型中有2个实体用户通知 (并且您有DTO对象来表示它),当您在映射表达式中没有设置MaxDepth的用户自动映射器时,“休斯顿我们有问题”:)。

The code below show a workaround to resolve this for all Mappers. 下面的代码显示了解决所有Mappers的解决方法。 If you want can be defined to each mapper. 如果你想要可以定义到每个mapper。 Like this Question 喜欢这个问题

Solution 1 (Global Definition) 解决方案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);
                });
        }
    }

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

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

Consider the following instead: 请考虑以下内容:

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

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

public class AddressDTO
{
    ....
}

Your DTO objects need to have the same structure as your domain objects for the default mapping conventions to work in AutoMapper. 您的DTO对象需要具有与域对象相同的结构,以便在AutoMapper中使用默认的映射约定。

Look at this: https://github.com/AutoMapper/AutoMapper/wiki/Projection It will explain the Projection for you, you could customize it to work the way you have it. 看看这个: https//github.com/AutoMapper/AutoMapper/wiki/Projection它会为你解释投影,你可以自定义它以你的方式工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM