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

使用AutoMapper映射嵌套属性时CustomerName为空的问题排查

问题描述

我有互相关联的Customer和Sale两张表,尝试将Sale实体映射到SaleDto以展示客户名称。已定义实体类和DTO,配置AutoMapper将Sale.Customer.Name映射到SaleDto.CustomerName,但调用API后返回的CustomerName为null,请求解决该问题。

相关代码如下:

Customer 实体类

public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }

    public ICollection<Sale>? Sales { get; set; }
}

Sale 实体类

public class Sale
{
    public int Id { get; set; }

    public int CustomerId { get; set; }

    public DateTime? Created { get; set; }

    public Customer? Customer { get; set; }

    public ICollection<SaleOrder>? SaleOrders { get; set; }
}

SaleDto

public class SaleDto
{
    public int Id { get; set; }

    public int CustomerId { get; set; }

    public string CustomerName { get; set; }

    public DateTime? Created { get; set; }
}

AutoMapper 配置

public MappingProfiles()
{
    CreateMap<Sale, SaleDto>()
        .ForMember(dest => dest.CustomerName,
        opt => opt.MapFrom(src => src.Customer.Name));             
}

API 代码

[HttpGet]
[ProducesResponseType(200, Type = typeof(IEnumerable<Sale>))]
public IActionResult GetSales()
{
    var sales = _mapper.Map<List<SaleDto>>(_saleRepository.GetSales());

    if (!ModelState.IsValid)
        return BadRequest(ModelState);

    return Ok(sales);
}

返回结果

[
  {
    "id": 1,
    "customerId": 1,
    "customerName": null,
    "amount": 2325,
    "created": "2023-07-10T22:25:49.3510244"
  }
]
解决方案

问题核心是EF Core未加载Sale实体关联的Customer导航属性,导致映射时src.Customer为null,最终CustomerName取不到值。提供两种解决思路:

1. 显式加载关联属性(推荐)

修改仓储中的GetSales方法,使用Include强制加载Customer:

public IEnumerable<Sale> GetSales()
{
    return _context.Sales.Include(s => s.Customer).ToList();
}

若使用异步查询,对应改为Include(s => s.Customer).ToListAsync()。

2. 启用延迟加载(按需选择)

如果项目场景适合延迟加载,可在EF上下文配置中开启:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseSqlServer("你的数据库连接字符串")
                  .UseLazyLoadingProxies();
}

同时需将Sale实体中的Customer属性改为virtual:

public virtual Customer? Customer { get; set; }

注意:延迟加载可能引发N+1查询问题,需根据业务场景评估使用。

额外优化:空值防护

为避免Customer为null时抛出异常,可在AutoMapper映射中添加空值判断:

CreateMap<Sale, SaleDto>()
    .ForMember(dest => dest.CustomerName,
    opt => opt.MapFrom(src => src.Customer?.Name ?? string.Empty));

内容的提问来源于stack exchange,提问作者user22219327

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 12:05:14