使用AutoMapper映射C#父子关联表时CategoryName为空问题求助
解决AutoMapper映射父子关联表时CategoryName为null的问题
问题场景
在C#中使用AutoMapper将TechSubcategory实体映射到TechSubCategoryDto时,CategoryId可正常映射,但CategoryName始终显示为null。
相关代码
父实体类(TechCategory)
public class TechCategory : AuditableBaseEntity { public int TechCategoryId { get; set; } public string TechCategoryName { get; set; } public string Description { get; set; } public string Initial { get; set; } public virtual ICollection<TechSubcategory> TechSubCategories { get; set; } }
子实体类(TechSubcategory)
public class TechSubcategory : AuditableBaseEntity { public int TechSubcategoryId { get; set; } public string TechSubcategoryName { get; set; } public string Description { get; set; } public string Initial { get; set; } public int? TechCategoryId { get; set; } public virtual TechCategory TechCategory { get; set; } }
DTO类(TechSubCategoryDto)
public class TechSubCategoryDto { public int TechSubcategoryId { get; set; } public string TechSubcategoryName { get; set; } public string Description { get; set; } public string Initial { get; set; } public int CategoryId { get; set; } public string CategoryName { get; set; } public DateTime CreateDate { get; set; } public DateTime ModifiedDate { get; set; } }
AutoMapper配置类
public class AutoMapperConfig: Profile { public AutoMapperConfig() { CreateMap<TechCategory, TechCategoryDto>().ReverseMap(); CreateMap<TechSubcategory, TechSubCategoryDto>() .ForMember(x => x.CategoryId, opt => opt.MapFrom(x => x.TechCategoryId)) .ForMember(x => x.CategoryName, opt => opt.MapFrom(x => x.TechCategory.TechCategoryName)) .ReverseMap(); } }
Controller代码
[HttpGet] [Route("All", Name = "GetAllSubCategory")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task<ActionResult<IEnumerable<TechSubCategoryDto>>> GetSubCategoryAsync() { var subCat = await _subCategoryRepository.GetAllAsync(); var catDto = _mapper.Map<List<TechSubCategoryDto>>(subCat); return Ok(catDto); }
问题原因
核心原因是EF Core未加载TechSubcategory的TechCategory导航属性。默认情况下,EF Core不会自动加载关联实体,导致TechCategory为null,AutoMapper无法获取TechCategoryName值。
解决方案
方法1:显式Include关联实体
修改仓储层的GetAllAsync方法,使用Include强制加载关联的TechCategory:
public async Task<IEnumerable<TechSubcategory>> GetAllAsync() { return await _context.TechSubcategories .Include(subCat => subCat.TechCategory) // 加载关联的TechCategory实体 .ToListAsync(); }
方法2:启用EF Core延迟加载(可选)
如果项目适合延迟加载模式,可通过以下步骤启用:
- 确保导航属性(如
TechSubcategory.TechCategory)已标记为virtual(你的代码已满足) - 在DbContext配置中启用延迟加载代理:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer("你的数据库连接字符串") .UseLazyLoadingProxies(); // 启用延迟加载 }
注意:延迟加载可能引发N+1查询性能问题,需根据业务场景评估是否使用。
额外优化:空值安全映射
为避免TechCategory为null时抛出空引用异常,可在AutoMapper配置中添加空值判断:
CreateMap<TechSubcategory, TechSubCategoryDto>() .ForMember(x => x.CategoryId, opt => opt.MapFrom(x => x.TechCategoryId)) .ForMember(x => x.CategoryName, opt => opt.MapFrom(x => x.TechCategory?.TechCategoryName)) // 使用空传播运算符 .ReverseMap();
内容的提问来源于stack exchange,提问作者Rovid kashyap
相关产品推荐
相关产品推荐

