AutoMapper C#映射问题:如何从Skills表获取SkillName?
解决AutoMapper映射时SkillName为空的问题
嘿,我来帮你搞定这个问题!你遇到的SkillName为null的核心原因其实很简单:你的EF查询里没有加载EmployeeSkill关联的Skill导航属性,所以当AutoMapper尝试访问src.Skill.SkillName时,src.Skill本身就是null,自然拿不到值。下面给你几个靠谱的解决方案:
方案1:查询时Include关联的Skill数据
最直接的方法,在查询EmployeeSkill的时候,把关联的Skill数据一起拉取回来:
List<EmployeeSkill> ski = context.EmployeeSkill .Include(e => e.Skill) // 关键:Include导航属性,加载Skill表的关联数据 .Where(r => !r.IsDeleted && r.EmployeeID == employeeID) .ToList();
这样你之前写的ResolveUsing配置就能正常工作了,因为此时src.Skill已经有实际数据了。
方案2:用AutoMapper的ProjectTo直接投影(更推荐)
这个方法能一步到位,跳过先查实体再映射的步骤,直接让EF生成只包含你需要字段的SQL查询,性能更优:
// 先配置映射(ResolveUsing可以换成MapFrom,更直观) var config = new MapperConfiguration(cfg => { cfg.CreateMap<EmployeeSkill, EmployeeSkillDTO>() .ForMember(dest => dest.SkillName, opt => opt.MapFrom(src => src.Skill.SkillName)); }); // 直接用ProjectTo完成查询+映射 List<EmployeeSkillDTO> mapObj = context.EmployeeSkill .Where(r => !r.IsDeleted && r.EmployeeID == employeeID) .ProjectTo<EmployeeSkillDTO>(config) .ToList(); return mapObj;
这种方式下,EF会自动生成关联Skill表的SQL,只查询你需要的字段(包括SkillName),不用加载整个实体,效率更高。
方案3:检查EF导航属性的配置
如果上面两种方法都没效果,那可能是你的实体导航属性配置有问题,比如:
- 确认EmployeeSkill类中的
Skill属性是正确的导航属性,比如加了[ForeignKey("SkillID")]特性:
public class EmployeeSkill { public int SkillID { get; set; } [ForeignKey("SkillID")] public Skill Skill { get; set; } // 其他属性... }
或者在DbContext的OnModelCreating里用Fluent API配置关联关系:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<EmployeeSkill>() .HasOne(e => e.Skill) .WithMany() .HasForeignKey(e => e.SkillID); }
确保SkillID确实是EmployeeSkill表中关联Skill表的外键字段,字段名称也匹配。
补充一句:你之前的ResolveUsing配置本身是没问题的,但因为Skill导航属性没被加载,所以src.Skill是null,才导致SkillName为空。如果你的项目启用了EF延迟加载,甚至可能会抛出NullReferenceException哦。
内容的提问来源于stack exchange,提问作者Aya Abdelaziz
相关产品推荐
相关产品推荐

