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

如何编写ForAllMaps函数:实现条件映射且避免异常、不影响其他映射

解决AutoMapper中条件映射避免异常的问题

我明白你遇到的困扰了——直接调用ForMember会在目标类型没有对应属性时抛出异常,还得保证不影响其他已有的映射配置。核心思路就是先判断条件是否满足,再执行映射配置,而不是不管三七二十一就调用ForMember。

解决方案代码

下面这段代码完美匹配你的需求:先检查源类型是否有Id属性,再检查目标类型是否存在[源类型名称]Id属性,只有两个条件都满足时才配置映射:

ForAllMaps((typeMap, mappingExpression) =>
{
    // 检查源类型是否包含公共实例的Id属性
    var sourceIdProp = typeMap.SourceType.GetProperty("Id", 
        BindingFlags.Public | BindingFlags.Instance);
    if (sourceIdProp == null)
    {
        return; // 源没有Id属性,直接跳过
    }

    // 构建目标属性名:源类型名称 + "Id"(比如Company → CompanyId)
    var targetPropName = $"{typeMap.SourceType.Name}Id";

    // 检查目标类型是否包含对应的公共实例属性
    var targetProp = typeMap.DestinationType.GetProperty(targetPropName, 
        BindingFlags.Public | BindingFlags.Instance);
    if (targetProp != null)
    {
        // 两个条件都满足,配置映射
        mappingExpression.ForMember(targetPropName, opt => opt.MapFrom(sourceIdProp.Name));
    }
});

关键细节说明

  1. 避免异常的核心:通过反射提前检查目标属性是否存在,只有存在时才调用ForMember,从根源上避免了属性不存在导致的异常。
  2. 不干扰其他映射:AutoMapper的规则优先级是手动配置 > 全局ForAllMaps配置,所以如果某个属性已经有手动或自动的映射规则,你的全局条件配置不会覆盖它,只会在没有规则且满足条件时添加新规则。
  3. 可选优化:如果需要支持大小写不敏感的属性匹配(比如目标属性是companyId而不是CompanyId),可以修改GetProperty的调用,加上忽略大小写的参数:
    var targetProp = typeMap.DestinationType.GetProperty(targetPropName, 
        BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
    

这样既实现了你想要的条件映射逻辑,又保证了整个映射配置的稳定性,不会因为属性不存在而崩溃,也不会影响其他已有的映射规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:05:36