You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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延迟加载(可选)

如果项目适合延迟加载模式,可通过以下步骤启用:

  1. 确保导航属性(如TechSubcategory.TechCategory)已标记为virtual(你的代码已满足)
  2. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 06:45:02