如何使用AutoMapper优雅地将扁平对象映射为复杂列表对象?
优化AutoMapper扁平类型到列表嵌套类型的映射
你的核心问题是手动逐个字段映射导致代码冗余、耦合度高,其实可以充分利用AutoMapper的自动映射规则和子类型映射定义来简化实现,完全不用手动new每个嵌套对象并赋值。
优化思路
- 先为所有匹配命名规则的子类型创建映射:AutoMapper会自动匹配同名属性,所以先定义
CustType→DTOCustObject、MyObject→DTOMyObject的映射,这部分不需要手动指定字段。 - 定义
CustType→ListObject的映射:因为ListObject只包含DTOCustObject属性,直接让AutoMapper把CustType映射成ListObject(内部会自动用第一步的子映射处理DTOCustObject)。 - 最后处理
FlatObject→MyDTO的映射:只需要把FlatObject.CustType映射为List<ListObject>,AutoMapper会自动复用之前的映射规则生成列表。
完整优化代码
using AutoMapper; var _config = new MapperConfiguration(cfg => { // 1. 子类型自动映射(字段名完全匹配,无需手动指定) cfg.CreateMap<CustType, DTOCustObject>(); cfg.CreateMap<MyObject, DTOMyObject>(); // 2. 把CustType映射为ListObject(AutoMapper自动填充DTOCustObject) cfg.CreateMap<CustType, ListObject>(); // 3. 主映射:将FlatObject的CustType转为List<ListObject> cfg.CreateMap<FlatObject, MyDTO>() .ForMember(dst => dst.ListObject, opt => opt.MapFrom(src => new List<ListObject> { src.CustType })); }); _config.AssertConfigurationIsValid(); var flatObject = new FlatObject { CustType = new CustType { MyString = "ABC123", MyInt = 12345, MyBool = true, MyObject = new MyObject { SomeString = "Some String Content" } } }; var mapper = new Mapper(_config); var myDTO = mapper.Map<MyDTO>(flatObject); Console.ReadKey(); // 实体类(保持不变) public class FlatObject { public CustType CustType { get; set; } = new CustType(); } public class CustType { public string? MyString { get; set; } public int MyInt { get; set; } public bool MyBool { get; set; } public MyObject MyObject { get; set; } = new MyObject(); } public class MyObject { public string? SomeString { get; set; } } // DTO类(保持不变) public class MyDTO { public List<ListObject> ListObject { get; set; } = new List<ListObject>(); } public class ListObject { public DTOCustObject DTOCustObject { get; set; } = new DTOCustObject(); } public class DTOCustObject { public string? MyString { get; set; } public int MyInt { get; set; } public bool MyBool { get; set; } public DTOMyObject DTOMyObject { get; set; } = new DTOMyObject(); } public class DTOMyObject { public string? SomeString { get; set; } }
优势说明
- 减少冗余代码:不用手动逐个赋值嵌套对象的每个字段,AutoMapper自动处理同名属性映射。
- 降低耦合:后续如果子类型(比如
CustType或DTOCustObject)新增/修改字段,只需要确保命名匹配,无需修改主映射逻辑。 - 可扩展性:如果未来需要把多个
CustType实例转为列表,只需要调整MapFrom的数据源(比如从单个对象改成集合),映射规则无需改动。
内容的提问来源于stack exchange,提问作者Display name
相关产品推荐
相关产品推荐

