如何使用AutoMapper将对象属性映射为有序对象列表?
使用AutoMapper将对象属性映射为有序对象列表的可行方案
可以通过AutoMapper实现该需求,以下是两种实用方案:
方案一:自定义值解析器(ValueResolver)
这种方式可以灵活配置属性与列表索引的映射关系,同时能依托AutoMapper的配置验证机制确保所有源属性都被处理。
实现代码
// 自定义值解析器,负责根据索引映射填充列表 public class PropertyToListResolver<TSource> : IValueResolver<TSource, List<object>, List<object>> { private readonly Dictionary<string, int> _propertyIndexMap; public PropertyToListResolver(Dictionary<string, int> propertyIndexMap) { _propertyIndexMap = propertyIndexMap; } public List<object> Resolve(TSource source, List<object> destination, List<object> destMember, ResolutionContext context) { // 初始化对应长度的数组 var resultArray = new object[_propertyIndexMap.Max(kv => kv.Value) + 1]; foreach (var kvp in _propertyIndexMap) { var propertyValue = source.GetType().GetProperty(kvp.Key).GetValue(source); resultArray[kvp.Value] = propertyValue; } return resultArray.ToList(); } } // 配置与使用 var propertyIndexMap = new Dictionary<string, int> { { nameof(Employee.Id), 0 }, { nameof(Employee.FirstName), 1 }, { nameof(Employee.LastName), 2 } }; var configuration = new MapperConfiguration(cfg => { var map = cfg.CreateMap<Employee, List<object>>(MemberList.Source) .ForMember(dest => dest, opt => opt.ResolveUsing(new PropertyToListResolver<Employee>(propertyIndexMap))); // 标记所有源属性已被处理,确保配置验证通过 foreach (var prop in typeof(Employee).GetProperties()) { map.ForSourceMember(prop.Name, opt => opt.DoNotValidate()); } }); configuration.AssertConfigurationIsValid(); var mapper = configuration.CreateMapper(); var employee = new Employee { FirstName = "foo", LastName = "bar", Id = 0 }; var listOfProperties = mapper.Map<List<object>>(employee); // 输出结果:[0, "foo", "bar"]
说明
自定义解析器通过传入的索引配置字典,将每个源属性值放到列表对应位置;通过反射遍历源属性并标记DoNotValidate,避免AutoMapper因目标列表无对应成员而抛出未映射错误。
方案二:AfterMap回调
这种方式更直接,在AutoMapper完成基础映射后,手动按指定顺序填充列表,同样能保证配置验证。
实现代码
var configuration = new MapperConfiguration(cfg => { var map = cfg.CreateMap<Employee, List<object>>(MemberList.Source) .AfterMap((src, dest) => { // 按需求顺序添加属性值 dest.Add(src.Id); dest.Add(src.FirstName); dest.Add(src.LastName); }); // 批量标记源属性已处理 foreach (var prop in typeof(Employee).GetProperties()) { map.ForSourceMember(prop.Name, opt => opt.DoNotValidate()); } }); configuration.AssertConfigurationIsValid(); var mapper = configuration.CreateMapper(); var employee = new Employee { FirstName = "foo", LastName = "bar", Id = 0 }; var listOfProperties = mapper.Map<List<object>>(employee); // 输出结果:[0, "foo", "bar"]
说明
AfterMap回调在基础映射完成后执行,直接按预设顺序填充列表;同样需要标记源属性已处理,确保AssertConfigurationIsValid()验证通过。
内容的提问来源于stack exchange,提问作者Bartosz
相关产品推荐
相关产品推荐

