[英]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.