AutoMapper: When mapping to the same destination member from 2 different source members, the second source member is not mapping

huangapple go评论77阅读模式
英文:

AutoMapper: When mapping to the same destination member from 2 different source members, the second source member is not mapping

问题

我正在尝试将包含多种类型的SourceCar模型映射到DestinationCar,但是当尝试从2个不同的源映射到同一个对象时,我遇到了困难。Model DestinationDriverInfo应该在映射结果中保存其两个属性的值,但只有NumberOfYearsDriving属性有值,NumberOfClaims属性没有值。

模型和映射配置如下:

执行:

期望的结果:

DestinationDriverInfo的属性都应该被填充。(NumberOfYearsDriving和NumberOfClaims)

实际结果:

只有DestinationDriverInfo内部的NumberOfYearsDriving属性从源映射。

附注:

源模型不能更改。

这里是一个可执行的示例:https://gist.github.com/ReeceDigital/1944cfea50900de9feb83df8112e1266

谢谢!

英文:

I am trying to map a SourceCar model containing multiple types, to a DestinationCar but I am struggling when trying to map to the same object from 2 different sources. The Model DestinationDriverInfo should hold the value for both of its properties in the mapping result, but it only holds a value for NumberOfYearsDriving not for NumberOfClaims.

Models and Mapping Configuration below:

AutoMapper: When mapping to the same destination member from 2 different source members, the second source member is not mapping

Execution:

AutoMapper: When mapping to the same destination member from 2 different source members, the second source member is not mapping

Expected Result:

Properties belonging to DestinationDriverInfo should both be populated. (NumberOfYearsDriving & NumberOfClaims)

Actual Result:

Only NumberOfYearsDriving property inside DestinationDriverInfo is mapped from source.

PS:
The source models cannot be changed.

Here is an executable example:
https://gist.github.com/ReeceDigital/1944cfea50900de9feb83df8112e1266

Thanks!

答案1

得分: 2

以下是您的配置:

var config = new MapperConfiguration(c =>
{
    c.CreateMap<SourceCar, DestinationCar>()
        .ForMember(dest => dest.Driver, opt => opt.MapFrom(src => src.Info));
                
    c.CreateMap<SourceInfo, DestinationDriver>()
        .ForMember(dest => dest.DriverInfo, opt => opt.MapFrom(src => src.GeneralInfo));
                
    c.CreateMap<SourceGeneralInfo, DestinationDriverInfo>()
        .ForMember(dest => dest.NumberOfClaims, opt => opt.MapFrom(src => src.Claim.NumClaims))
        .ForMember(dest => dest.NumberOfYearsDriving, opt => opt.MapFrom(src => src.Driver.NumDriving));
});

这样,您可以直接将SourceInfo的嵌套对象和属性映射到DestinationDriver的属性,并且它将与当前结构一起工作。

如果您不需要能够将对象从SourceClaim转换为DestinationDriverInfo,或者从SourceDriver转换为DestinationDriverInfo,并且不需要直接使用父对象,那么以上配置就足够了。否则,您也可以将这些映射添加到配置中:

var config = new MapperConfiguration(c =>
{
    c.CreateMap<SourceCar, DestinationCar>()
        .ForMember(dest => dest.Driver, opt => opt.MapFrom(src => src.Info));
                
    c.CreateMap<SourceInfo, DestinationDriver>()
        .ForMember(dest => dest.DriverInfo, opt => opt.MapFrom(src => src.GeneralInfo));
                
    c.CreateMap<SourceGeneralInfo, DestinationDriverInfo>()
        .ForMember(dest => dest.NumberOfClaims, opt => opt.MapFrom(src => src.Claim.NumClaims))
        .ForMember(dest => dest.NumberOfYearsDriving, opt => opt.MapFrom(src => src.Driver.NumDriving));

    c.CreateMap<SourceDriver, DestinationDriverInfo>()
        .ForMember(dest => dest.NumberOfYearsDriving, opt => opt.MapFrom(src => src.NumDriving))
        .ForMember(dest => dest.NumberOfClaims, opt => opt.Ignore());

    c.CreateMap<SourceClaim, DestinationDriverInfo>()
        .ForMember(dest => dest.NumberOfClaims, opt => opt.MapFrom(src => src.NumClaims))
        .ForMember(dest => dest.NumberOfYearsDriving, opt => opt.Ignore());
});
英文:

Here is your config:

var config = new MapperConfiguration(c =&gt;
{
    c.CreateMap&lt;SourceCar, DestinationCar&gt;()
        .ForMember(dest =&gt; dest.Driver, opt =&gt; opt.MapFrom(src =&gt; src.Info));
                
    c.CreateMap&lt;SourceInfo, DestinationDriver&gt;()
        .ForMember(dest =&gt; dest.DriverInfo, opt =&gt; opt.MapFrom(src =&gt; src.GeneralInfo));
                
    c.CreateMap&lt;SourceGeneralInfo, DestinationDriverInfo&gt;()
        .ForMember(dest =&gt; dest.NumberOfClaims, opt =&gt; opt.MapFrom(src =&gt; src.Claim.NumClaims))
        .ForMember(dest =&gt; dest.NumberOfYearsDriving, opt =&gt; opt.MapFrom(src =&gt; src.Driver.NumDriving));
});

So you can map SourceInfo with nested objects and its properties directly to the DestinationDriver properties and it will work with current structure.

If you do not need to be able to convert objects from SourceClaim to DestinationDriverInfo or from SourceDriver to DestinationDriverInfo additionally directly without parent objects, this will enough. Otherwise you can also add these mappings to the configuration:

var config = new MapperConfiguration(c =&gt;
{
    c.CreateMap&lt;SourceCar, DestinationCar&gt;()
        .ForMember(dest =&gt; dest.Driver, opt =&gt; opt.MapFrom(src =&gt; src.Info));
                
    c.CreateMap&lt;SourceInfo, DestinationDriver&gt;()
        .ForMember(dest =&gt; dest.DriverInfo, opt =&gt; opt.MapFrom(src =&gt; src.GeneralInfo));
                
    c.CreateMap&lt;SourceGeneralInfo, DestinationDriverInfo&gt;()
        .ForMember(dest =&gt; dest.NumberOfClaims, opt =&gt; opt.MapFrom(src =&gt; src.Claim.NumClaims))
        .ForMember(dest =&gt; dest.NumberOfYearsDriving, opt =&gt; opt.MapFrom(src =&gt; src.Driver.NumDriving));

    c.CreateMap&lt;SourceDriver, DestinationDriverInfo&gt;()
        .ForMember(dest =&gt; dest.NumberOfYearsDriving, opt =&gt; opt.MapFrom(src =&gt; src.NumDriving))
        .ForMember(dest =&gt; dest.NumberOfClaims, opt =&gt; opt.Ignore());

    c.CreateMap&lt;SourceClaim, DestinationDriverInfo&gt;()
        .ForMember(dest =&gt; dest.NumberOfClaims, opt =&gt; opt.MapFrom(src =&gt; src.NumClaims))
        .ForMember(dest =&gt; dest.NumberOfYearsDriving, opt =&gt; opt.Ignore());
});

huangapple
  • 本文由 发表于 2023年3月7日 19:44:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/75661558.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定