如何在AutoMapper映射时为List中每个类的整数属性递增值?
问题:AutoMapper映射时实现IncrementNo递增值需求
现有两个类定义:
public class DBEmployee { public Guid EmpId {get;set;} public string Name {get;set;} public int IncrementNo {get;set;} } public class C#Employee { public Guid EmpId {get;set;} public string Name {get;set;} public int IncrementNo {get;set;} }
从数据库获取的员工列表:
var listOfEmployees = new List<DBEmployee> { new DBEmployee { EmpId = Guid.Parse("e31d712a-7d5c-4b1c-99a8-306f9aebbfa0"), Name = "AAA", IncrementNo = 0 }, new DBEmployee { EmpId = Guid.Parse("87c4feed-20e7-42b2-8a95-8acb0743fdfe"), Name = "BBB", IncrementNo = 0 }, new DBEmployee { EmpId = Guid.Parse("90cdd219-8796-4d51-bfe1-add8515315c5"), Name = "CCC", IncrementNo = 0 }, };
当前使用AutoMapper的配置如下,映射后所有员工的IncrementNo都为1,需求是让AAA的IncrementNo为1、BBB为2、CCC为3,希望直接在AutoMapper配置中实现,避免额外循环:
var config = new MapperConfiguration(cfg => cfg.CreateMap<DBEmployee, C#Employee>() .AfterMap((src, dest) => dest.IncrementNo= dest.IncrementNo+ 1) ); var mapper = new Mapper(config); var c#Emps = mapper.Map<List<C#Employee>>(listOfEmployees);
解决方案
方法一:自定义列表到列表的映射转换器
直接配置List<DBEmployee>到List<C#Employee>的自定义转换逻辑,在转换过程中利用元素索引设置递增值:
var config = new MapperConfiguration(cfg => { // 配置单个对象的基础字段映射 cfg.CreateMap<DBEmployee, C#Employee>(); // 自定义列表转换逻辑 cfg.CreateMap<List<DBEmployee>, List<C#Employee>>().ConvertUsing((sourceList, _, context) => { var result = new List<C#Employee>(); for (int i = 0; i < sourceList.Count; i++) { var mappedEmp = context.Mapper.Map<C#Employee>(sourceList[i]); mappedEmp.IncrementNo = i + 1; // 索引从0开始,+1得到1、2、3的递增值 result.Add(mappedEmp); } return result; }); }); var mapper = new Mapper(config); var c#Emps = mapper.Map<List<C#Employee>>(listOfEmployees);
这种方式逻辑直观,所有转换规则都集中在AutoMapper配置中,无需额外循环代码。
方法二:利用映射上下文传递计数器
通过AutoMapper的Context.Items传递计数器,在单个对象映射时更新并赋值:
var config = new MapperConfiguration(cfg => { cfg.CreateMap<DBEmployee, C#Employee>() .ForMember(dest => dest.IncrementNo, opt => opt.MapFrom((src, _, __, context) => { // 初始化计数器(首次映射时) if (!context.Items.ContainsKey("IncrementCounter")) { context.Items["IncrementCounter"] = 0; } var counter = (int)context.Items["IncrementCounter"]; context.Items["IncrementCounter"] = counter + 1; return counter + 1; })); }); var mapper = new Mapper(config); // 映射前初始化上下文计数器 var c#Emps = mapper.Map<List<C#Employee>>(listOfEmployees, opt => opt.Items["IncrementCounter"] = 0);
这种方式保持了单个对象映射的配置结构,但需要在映射列表时手动初始化计数器。
内容的提问来源于stack exchange,提问作者SAREKA AVINASH
相关产品推荐
相关产品推荐

