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

AutoMapper如何基于多源成员设置目标成员?状态映射为空排查

问题:AutoMapper映射Product到ViewProductDto时State始终为null

代码定义

ProductState类

public class ProductState
{
    public static ProductState OutOfService => new(1, "Out of Service", "bg-secondary");
    public static ProductState InService => new(2, "In Service", "bg-sucess");
    public static ProductState Repair => new(3, "Repair","bg-dark");
    public static ProductState Damaged => new(4, "Damaged","bg-warning text-dark");
    public static ProductState Scrapped => new(5, "Scrapped", "badge-danger");
    public static ProductState CheckedOut => new(6, "Checked Out", "bg-primary");

    public ProductState (int id, string name, string css)
    {
        Id = id;
        Name = name;
        CSS = css;
    }
    public int Id { get; set; }
    public string Name { get; set; }

    public string CSS { get; set; }
}

ViewProductDto类

public class ViewProductDto : BaseProductDto, IProductPartialDto
{
    public ProductState State { get; set; }
}

Product实体类

public class Product 
{
    public bool? IsDamaged { get; set; }
    public bool? IsScrapped { get; set; }
    public DateTime? WhenScrapped {get;set;}
    public List<InOut> Inout {get;set;}
    
}

AutoMapper注册(Startup.cs)

services.AddAutoMapper(config =>
{
    config.AddProfile(new ViewProductMapper());
    
}, AppDomain.CurrentDomain.GetAssemblies());

AutoMapper配置文件ViewProductMapper

public class ViewProductMapper : Profile
{
    public ViewProductMapper()
    {
        
        CreateMap<Product, ViewProductDto>()
       
        .ForMember(dest => dest.State, cfg => cfg.MapFrom(o=> MapProductState(o)))



    }
    private ProductState MapProductState(Product eqp)
    {
        if ((eqp.IsBeingScrapped.HasValue && eqp.IsBeingScrapped.Value) || eqp.ScrappedWhen.HasValue)
        {
            return ProductState.Scrapped;
        }
        else if ((eqp.IsDamage.HasValue && eqp.IsDamage.Value) && !((eqp.IsBeingScrapped.HasValue && eqp.IsBeingScrapped.Value) || eqp.ScrappedWhen.HasValue))
        {
            return ProductState.Damaged;
        }
        else if (eqp.Inout != null && eqp.Inout.Any(a => a.Out))
        {
            return ProductState.CheckedOut;
        }
        else
        {
            return ProductState.InService;
        }
    }

}

执行映射代码

_mapper.Map<List<Product>, List<ViewDto>>(products)

问题原因及修复方案

1. 属性名称不匹配(核心问题)

MapProductState方法中使用的属性名称与Product实体定义完全不符:

  • 实体中是IsDamaged,方法里写的是IsDamage(缺失末尾字母d)
  • 实体中是IsScrapped,方法里写的是IsBeingScrapped
  • 实体中是WhenScrapped,方法里写的是ScrappedWhen

这些错误会导致条件判断逻辑失效,甚至运行时抛出异常,最终AutoMapper无法正确赋值State。

修复后的映射方法:

private ProductState MapProductState(Product eqp)
{
    if ((eqp.IsScrapped.HasValue && eqp.IsScrapped.Value) || eqp.WhenScrapped.HasValue)
    {
        return ProductState.Scrapped;
    }
    else if ((eqp.IsDamaged.HasValue && eqp.IsDamaged.Value) && !((eqp.IsScrapped.HasValue && eqp.IsScrapped.Value) || eqp.WhenScrapped.HasValue))
    {
        return ProductState.Damaged;
    }
    else if (eqp.Inout != null && eqp.Inout.Any(a => a.Out))
    {
        return ProductState.CheckedOut;
    }
    else
    {
        return ProductState.InService;
    }
}

2. 映射目标类型笔误

执行映射时写的是List<ViewDto>,但实际DTO类型是ViewProductDto,类型不匹配会导致映射逻辑无法正确应用到目标属性。

修复后的映射调用:

_mapper.Map<List<Product>, List<ViewProductDto>>(products)

3. 可选:映射方法可见性优化

虽然AutoMapper理论上可以调用私有方法,但将MapProductState改为protected或public可避免潜在的访问权限问题:

protected ProductState MapProductState(Product eqp)
{
    // 逻辑同上
}

4. 可选:验证AutoMapper配置

添加配置验证可提前发现映射错误,避免运行时问题:

services.AddAutoMapper(config =>
{
    config.AddProfile(new ViewProductMapper());
}, AppDomain.CurrentDomain.GetAssemblies())
// 启用配置验证
.AddAutoMapperValidation();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 18:06:27