如何用AutoMapper将字符串集合按位置映射为对象集合属性?
解决方案
要实现按索引把Source的三个字符串集合映射成Destination的Vehicle集合,AutoMapper默认配置无法直接完成,需要自定义映射逻辑,下面是两种可行的实现方式:
方式一:使用Zip方法配对元素
利用LINQ的Zip方法依次将三个集合的对应元素配对,生成Vehicle对象:
var mapperConfig = new MapperConfiguration(cfg => { cfg.CreateMap<Source, Destination>() .ForMember(dest => dest.Vehicles, opt => opt.MapFrom(src => // 先配对Makes和Models,再和Variants配对 src.Makes.Zip(src.Models, (make, model) => new { Make = make, Model = model }) .Zip(src.Variants, (pair, variant) => new Vehicle { Makes = pair.Make, Models = pair.Model, Variants = variant }) )); }); // 实例化Mapper并使用 var mapper = mapperConfig.CreateMapper(); Source source = new Source { Makes = new List<string> { "Toyota", "Honda" }, Models = new List<string> { "Camry", "Civic" }, Variants = new List<string> { "SE", "EX" } }; Destination dest = mapper.Map<Destination>(source);
方式二:按索引遍历生成对象
如果觉得Zip嵌套不够直观,可以用Enumerable.Range遍历索引,直接取对应位置的元素,同时处理集合长度不一致的情况(取最短集合的长度,避免索引越界):
var mapperConfig = new MapperConfiguration(cfg => { cfg.CreateMap<Source, Destination>() .ForMember(dest => dest.Vehicles, opt => opt.MapFrom(src => { // 计算三个集合中最短的长度,防止索引越界 var counts = new[] { src.Makes?.Count() ?? 0, src.Models?.Count() ?? 0, src.Variants?.Count() ?? 0 }; var maxValidIndex = counts.Min(); if (maxValidIndex == 0) return Enumerable.Empty<Vehicle>(); // 按索引生成每个Vehicle对象 return Enumerable.Range(0, maxValidIndex) .Select(i => new Vehicle { Makes = src.Makes.ElementAt(i), Models = src.Models.ElementAt(i), Variants = src.Variants.ElementAt(i) }); })); });
注意事项
- 不需要配置
CreateMap<Source, Vehicle>,因为Source是包含集合的对象,和单个Vehicle没有直接属性对应关系,直接在Source到Destination的映射里生成Vehicle集合即可。 - 要处理集合为空的情况,避免出现
NullReferenceException或者索引越界错误。
内容的提问来源于stack exchange,提问作者Kaine
相关产品推荐
相关产品推荐

