在C# .NET6中使用AutoMapper将扁平对象映射为列表:列表始终为空的问题排查
问题分析
我来帮你拆解下问题核心——你当前的AutoMapper配置完全没关联到Origin到Destination的映射逻辑上,这才导致ListItem列表始终为空:
- 你给
Destination <-> NonListItem加了反向映射,还在里面写了生成ListItem列表的代码,但这个配置根本不会被AutoMapper触发。因为你实际要做的是Origin转Destination,AutoMapper不知道要把Origin.NonListItem和Destination.ListItem通过这个单独的映射关联起来。 - 默认情况下,AutoMapper只会对
Origin和Destination的同名属性做自动映射,而ListItem和NonListItem名字完全不同,所以这部分完全没被处理。
解决方案
直接在Origin -> Destination的映射配置里,用ForMember指定ListItem的生成规则,把Origin.NonListItem转换成包含单个ListItem的列表即可。
修正后的完整代码
using AutoMapper; MapperConfiguration config = new MapperConfiguration(x => { // 核心:在 Origin -> Destination 的映射里直接定义 ListItem 的生成逻辑 x.CreateMap<Origin, Destination>() .ForMember(dest => dest.ListItem, opt => opt.MapFrom(src => new List<ListItem> { new ListItem { ListInt = src.NonListItem.NonListInt, ListStr = src.NonListItem.NonListStr } })); // 如果你不需要从 Destination 转回 Origin,下面这段可以直接删掉 // 如果需要双向映射,再补充反向转换的规则 x.CreateMap<Destination, Origin>() .ForMember(dest => dest.NonListItem, opt => opt.MapFrom(src => src.ListItem.FirstOrDefault() != null ? new NonListItem { NonListInt = src.ListItem.First().ListInt, NonListStr = src.ListItem.First().ListStr } : new NonListItem())); }); var origin = new Origin(); origin.Id = 12345; origin.NonListItem.NonListInt = 54321; origin.NonListItem.NonListStr = "This is a test"; IMapper mapper = new Mapper(config); var destination = mapper.Map<Destination>(origin); // 可以加这段代码验证结果 Console.WriteLine($"Id: {destination.Id}"); Console.WriteLine($"ListItem 数量: {destination.ListItem.Count}"); if (destination.ListItem.Any()) { Console.WriteLine($"ListInt: {destination.ListItem[0].ListInt}"); Console.WriteLine($"ListStr: {destination.ListItem[0].ListStr}"); } Console.ReadKey(); // 实体类部分保持不变 public class Origin { public NonListItem NonListItem { get; set; } = new NonListItem(); public int Id { get; set; } } public class NonListItem { public int NonListInt { get; set; } public string? NonListStr { get; set; } } public class Destination { public int Id { get; set; } public List<ListItem> ListItem { get; set; } = new List<ListItem>(); } public class ListItem { public int ListInt { get; set; } public string? ListStr { get; set; } }
关键注意点
- 映射逻辑必须放在正确的转换路径上:你要的是
Origin转Destination,规则就必须定义在这个映射关系里,别搞岔了路径。 - 如果不需要反向转换(
Destination转Origin),直接删掉后面那段反向映射的代码,避免冗余。 - 要是
Origin.NonListItem有可能为null,记得在映射时加空值判断,防止出现空引用异常。
内容的提问来源于stack exchange,提问作者Display name
相关产品推荐
相关产品推荐

