使用AutoMapper映射结构不同的实体问题求助
解决AutoMapper源/目标实体结构差异的映射问题
嘿,我来帮你搞定这个AutoMapper的映射需求!先把你给出的源实体、枚举定义整理成可编译的代码(顺便修正了枚举里的笔误),再结合常见的目标实体场景,给你配置对应的映射规则。
首先是整理后的源实体与枚举代码
public class SourceEntity { public string Name { get; set; } public Type Type { get; set; } public Communication SelectedCommunication { get; set; } } public enum Type { Type1 = 1, Type2 = 2 // 修正了你原来的Typ2笔误 } [Flags] public enum Communication { Phone = 1, Email = 2, Post = 4 } // 假设你的HasFlag扩展方法实现如下 public static class CommunicationExtensions { public static bool HasFlag(this Communication communication, Communication flag) { return (communication & flag) == flag; } }
常见的目标实体示例(补全你未写完的部分)
假设你的目标实体需要把Flags枚举拆成单独的布尔属性,同时把Type枚举转成名称字符串,定义如下:
public class DestinationEntity { public string Name { get; set; } public string TypeName { get; set; } // 存储Type枚举的名称 public bool HasPhone { get; set; } // 是否选中Phone通信 public bool HasEmail { get; set; } // 是否选中Email通信 public bool HasPost { get; set; } // 是否选中Post通信 }
AutoMapper映射配置
创建一个自定义的Profile类,来定义源到目标的映射规则:
public class EntityMappingProfile : Profile { public EntityMappingProfile() { CreateMap<SourceEntity, DestinationEntity>() // 同名属性AutoMapper会自动映射,这里写出来是为了清晰,也可以省略 .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name)) // 将Type枚举转为字符串名称,也可以转成数值:src => (int)src.Type .ForMember(dest => dest.TypeName, opt => opt.MapFrom(src => src.Type.ToString())) // 利用你的HasFlag扩展方法判断每个通信标记是否被选中 .ForMember(dest => dest.HasPhone, opt => opt.MapFrom(src => src.SelectedCommunication.HasFlag(Communication.Phone))) .ForMember(dest => dest.HasEmail, opt => opt.MapFrom(src => src.SelectedCommunication.HasFlag(Communication.Email))) .ForMember(dest => dest.HasPost, opt => opt.MapFrom(src => src.SelectedCommunication.HasFlag(Communication.Post))); } }
映射使用示例
初始化AutoMapper并完成映射:
// 初始化Mapper配置 var config = new MapperConfiguration(cfg => cfg.AddProfile<EntityMappingProfile>()); var mapper = config.CreateMapper(); // 构造测试用的源实体 var source = new SourceEntity { Name = "测试实体", Type = Type.Type1, SelectedCommunication = Communication.Phone | Communication.Email // 同时选中电话和邮件 }; // 执行映射 var destination = mapper.Map<DestinationEntity>(source); // 最终结果: // destination.Name = "测试实体" // destination.TypeName = "Type1" // destination.HasPhone = true // destination.HasEmail = true // destination.HasPost = false
额外说明
- 如果你的
HasFlag扩展方法没有自定义逻辑,其实可以直接用.NET自带的Enum.HasFlag方法,效果完全一致。 - 如果目标实体的结构是其他形式(比如把Flags枚举转成逗号分隔的字符串),可以调整映射规则,比如:
.ForMember(dest => dest.CommunicationList, opt => opt.MapFrom(src => string.Join(", ", Enum.GetValues(typeof(Communication)) .Cast<Communication>() .Where(flag => src.SelectedCommunication.HasFlag(flag)) .Select(f => f.ToString())))) - 记得修正
Type枚举里的笔误,否则编译会报错哦~
内容的提问来源于stack exchange,提问作者Gleb
相关产品推荐
相关产品推荐

