如何使用AutoMapper映射XML片段至嵌套Record类型
问题描述
需要将一段XML片段映射到包含嵌套Record的Record结构中,必须通过ConstructUsing()方法提供构造函数所需的全部参数。在配置ParentRecord的映射规则时,不知道如何正确指定第二个参数(ChildRecord类型),同时避免递归问题,猜测可以借助已创建的mapper实例来实现类似return new ParentRecord(ele.Attribute("id").Value, mapper.Map<ChildRecord>(ele));的逻辑,但不清楚具体写法。
XML片段
XElement xe = new XElement("root", new XElement("parent", new XAttribute("id", "123"), new XElement("child", "some text")));
Records定义
public record ParentRecord(long Id, ChildRecord Child); public record ChildRecord(string Text);
原始映射配置
var configuration = new MapperConfiguration(cfg => { cfg.CreateMap<XElement, ChildRecord>() .ConstructUsing((ele, ctx) => { return new ChildRecord(ele.Element("child").Value); }); cfg.CreateMap<XElement, ParentRecord>() .ConstructUsing((ele, ctx) => { return new ParentRecord(ele.Attribute("id").Value, ?WHAT_TO_PUT_HERE?); }); }); var mapper = configuration.CreateMapper();
映射请求
var o = mapper.Map<ParentRecord>(xe.Element("parent"));
解决方案
可以利用ConstructUsing方法提供的ResolutionContext参数(即代码中的ctx),通过其Mapper属性完成嵌套对象的映射,同时注意将id属性的字符串值转换为long类型,避免类型不匹配错误。修改后的ParentRecord映射配置如下:
var configuration = new MapperConfiguration(cfg => { cfg.CreateMap<XElement, ChildRecord>() .ConstructUsing((ele, ctx) => { return new ChildRecord(ele.Element("child").Value); }); cfg.CreateMap<XElement, ParentRecord>() .ConstructUsing((ele, ctx) => { // 转换id为long类型,并用ctx.Mapper完成ChildRecord的映射 var id = long.Parse(ele.Attribute("id").Value); var child = ctx.Mapper.Map<ChildRecord>(ele); return new ParentRecord(id, child); }); }); var mapper = configuration.CreateMapper();
这样既无需提前引用外部mapper实例,也不会触发递归问题,AutoMapper会通过上下文正确处理嵌套映射逻辑。
内容的提问来源于stack exchange,提问作者phil
相关产品推荐
相关产品推荐

