如何使用AutoMapper将Customer与Person合并映射为CustomerModel?
问题背景
现有以下C#类定义:
Customer类
public class Customer { public int Id { get; set; } public int PersonId { get; set; } public int DiscountValue { get; set; } public Person Person { get; set; } public ICollection<Receipt> Receipts { get; set; } }
Person类
public class Person { public int Id { get; set; } public string Name { get; set; } public string Surname { get; set; } public DateTime BirthDate { get; set; } }
CustomerModel类
public class CustomerModel { public int Id { get; set; } public string Name { get; set; } public string Surname { get; set; } public DateTime BirthDate { get; set; } public int DiscountValue { get; set; } public ICollection<int> ReceiptsIds { get; set; } }
需要将Customer和Person合并映射为CustomerModel,当前的AutoMapper配置尝试使用元组但未完善映射规则,以下是两种场景下的正确实现:
场景1:Customer已关联Person导航属性
如果你的Customer对象已通过EF Core等方式加载了Person导航属性(即customer.Person不为null),可直接基于Customer配置映射,无需传入元组:
public class AutomapperProfile : Profile { public AutomapperProfile() { CreateMap<Customer, CustomerModel>() // 自动匹配的属性可省略显式配置,这里写出是为了清晰 .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id)) .ForMember(dest => dest.DiscountValue, opt => opt.MapFrom(src => src.DiscountValue)) // 映射Person导航属性的字段 .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Person.Name)) .ForMember(dest => dest.Surname, opt => opt.MapFrom(src => src.Person.Surname)) .ForMember(dest => dest.BirthDate, opt => opt.MapFrom(src => src.Person.BirthDate)) // 将Receipts集合转换为Id集合,处理空集合避免异常 .ForMember(dest => dest.ReceiptsIds, opt => opt.MapFrom(src => src.Receipts?.Select(r => r.Id) ?? new List<int>())); } }
使用方式:
var customerModel = mapper.Map<CustomerModel>(customer);
场景2:需传入独立的Customer和Person实例(元组方式)
如果必须通过元组传递两个独立的实例,需明确指定每个属性的来源是元组的第一个或第二个元素:
public class AutomapperProfile : Profile { public AutomapperProfile() { CreateMap<(Customer Customer, Person Person), CustomerModel>() // 从Customer实例取属性 .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Customer.Id)) .ForMember(dest => dest.DiscountValue, opt => opt.MapFrom(src => src.Customer.DiscountValue)) .ForMember(dest => dest.ReceiptsIds, opt => opt.MapFrom(src => src.Customer.Receipts?.Select(r => r.Id) ?? new List<int>())) // 从Person实例取属性 .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Person.Name)) .ForMember(dest => dest.Surname, opt => opt.MapFrom(src => src.Person.Surname)) .ForMember(dest => dest.BirthDate, opt => opt.MapFrom(src => src.Person.BirthDate)); } }
使用方式:
var customerModel = mapper.Map<CustomerModel>((customer, person));
注意事项
- 处理
Receipts空集合时,用?.Select()和空合并运算符避免空引用异常 - 属性名称完全匹配时,AutoMapper会自动映射,可省略对应
.ForMember配置,显式写出是为了提升代码可读性
内容的提问来源于stack exchange,提问作者Fatality99
相关产品推荐
相关产品推荐

