如何在AutoMapper Profile中根据源实体值手动赋值DTO属性?
问题
我想在AutoMapper的Profile中,根据源实体的属性值手动给DTO的属性赋值。但下面的代码没达到预期效果——因为.AfterMap不受.Condition约束,导致所有dest.Sent都被设为true:
.ForMember( dest => dest.Sent, opts => opts.Condition(src => src.Status == 2 && src.Status != 1) ) .AfterMap((notification, dto) => dto.Sent = true);
我的DTO类:
public class NotificationItemDTO { public long Id { get; set; } public string Title { get; set; } public string Description { get; set; } public string Type { get; set; } public bool Sent { get; set; } }
源实体类:
public class Notification { public long Id { get; set; } public string Title { get; set; } public string Description { get; set; } public string Type { get; set; } public int Status { get; set; } }
需求是:根据源实体的Status(int类型)为DTO的Sent(bool类型)赋值——当src.Status == 1时,dest.Sent = false;当src.Status == 2时,dest.Sent = true。请问怎么实现?
解决方案
有几种简洁的方式可以实现这个需求,避免原代码的逻辑问题:
方法1:使用MapFrom直接映射
这是最直观的实现方式,直接在ForMember中通过MapFrom根据源状态计算目标值:
.CreateMap<Notification, NotificationItemDTO>() .ForMember(dest => dest.Sent, opts => opts.MapFrom(src => src.Status == 2));
如果需要明确处理所有分支(包括Status既不是1也不是2的情况),可以扩展逻辑:
.MapFrom(src => src.Status switch { 2 => true, 1 => false, _ => false // 其他状态的默认值,可根据需求调整 })
方法2:在AfterMap中加入条件判断
如果一定要使用AfterMap,直接在回调里根据源状态设置目标值即可,不需要额外添加Condition:
.CreateMap<Notification, NotificationItemDTO>() .AfterMap((src, dest) => { if (src.Status == 1) dest.Sent = false; else if (src.Status == 2) dest.Sent = true; else dest.Sent = false; // 处理其他状态的默认值 });
方法3:使用ResolveUsing(适合复杂逻辑)
如果映射逻辑后续可能变得复杂,可以用ResolveUsing封装判断逻辑:
.CreateMap<Notification, NotificationItemDTO>() .ForMember(dest => dest.Sent, opts => opts.ResolveUsing(src => { return src.Status switch { 1 => false, 2 => true, _ => false }; }));
以上方法都能精准控制Sent属性的赋值,不会出现原代码中所有值被统一设为true的问题。
内容的提问来源于stack exchange,提问作者Michela Cani
相关产品推荐
相关产品推荐

