简体   繁体   English

自动映射器基于父值映射子对象

[英]Automapper map child object based on parent value

If the header object has a prop set to 1 then it should map field type1 in the child to type in the destination. 如果标头对象的prop设置为1,则它应该在子级中映射字段type1以键入目标。 Otherwise it should use type2. 否则,应使用type2。

Bonus points if I can use IValueResolver to use type1 or type1extended if extended is filled. 如果我可以使用IValueResolver来使用type1或type1extended(如果已填充extended),则可以得到加分。

Here is my minimum viable product/demo 这是我的最低可行产品/演示

using AutoMapper;
using AutoMapper.Configuration.Conventions;
using System;
using System.Collections.Generic;

namespace ConsoleAppAutoMapper
{
    class Program
    {
        static void Main(string[] args)
        {
            var source = new SourceParent() {
                Header = new SourceHeader() { Currency = 30, FileName = "testfile.txt", Type = 1 },
                Rows = new List<SourceRow>() {
                    new SourceRow() { ID = 1, Amount1 = 100, Amount2 = 200 },
                    new SourceRow() { ID = 2, Amount1 = 101, Amount2 = 201 },
                    new SourceRow() { ID = 3, Amount1 = 102, Amount2 = 202 }
                } };

            var config = new MapperConfiguration(cfg => {
                cfg.CreateMap<SourceParent, DestinationParent>();
                cfg.CreateMap<SourceRow, DestinationRow>()
                    .ForMember(x => x.Type, opt => opt.MapFrom(p => p.Type1));
            });

            var mapper = config.CreateMapper();
            var dest = mapper.Map<DestinationParent>(source);

            Console.WriteLine(dest.Rows[0].Type == 100); // should be true if SourceHeader.Type = 1 and should be 200 (SourceRow.Type2) if SourceHeader.Type = 2
            Console.ReadKey();
        }
    }

    // source

    public class SourceParent
    {
        public SourceHeader Header { get; set; }
        public List<SourceRow> Rows { get; set; }
    }

    public class SourceHeader
    {
        public string FileName { get; set; }
        public int Type { get; set; }
    }

    public class SourceRow
    {
        public int ID { get; set; }
        public int Amount1 { get; set; }
        public int Amount2 { get; set; }
    }

    //destination

    public class DestinationParent
    {
        public DestinationHeader Header { get; set; }
        public List<DestinationRow> Rows { get; set; }
    }

    public class DestinationHeader
    {
        public string FileName { get; set; }
    }

    public class DestinationRow
    {
        public int ID { get; set; }
        public int Type { get; set; }
        public int Amount{ get; set; }  // if type=1 then source is amount1 otherwise amount2
    }
}

edit I tried to solve it by having an Aftermap on the sourceparent mapping which took the value from the header and put it in a prop from the destinationrow (it is the Type value) and wanted another aftermap on the row to see if I needed prop A or B (type1 or type2) but that aftermap still does not know (it's null) what type it is because it happens before the aftermap of the parent it seems. 编辑我试图通过在sourceparent映射上放置一个Aftermap来解决这个Aftermap ,该映射从标头中获取值并将其放在destinationrow的prop中(它是Type值),并希望在该行上放置另一个aftermap来查看我是否需要prop A或B(type1或type2),但是该aftermap仍然不知道(它为null)它是什么类型,因为它发生在看起来像父对象的aftermap之前。

public class MapRowType : IMappingAction<SourceParent, DestinationParent>
{
    public void Process(SourceParentsource, DestinationParent destination)
    {
        foreach (var row in destination.Rows)
        {
            row.Type = source.Header.Type; // so now I have type in the row, but still do not know if I should use Amount1 or Amount2 
        }
    }
}

you can use the resolution context. 您可以使用解析上下文。 Declare the mapping: 声明映射:

cfg.CreateMap<SourceRow, DestinationRow>()
            .ForMember(x => x.Type, 
                       opt => opt.ResolveUsing((src, dest1, destMember, resContext) => resContext.Items["Type"] as int? == 1? src.Type2: src.Type1));

After pass the value: 传递值后:

var dest = mapper.Map<DestinationParent>(source, opts=> { opts.Items["Type"] = source.Header.Type;});

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

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