AutoMapper问题#3926的解决方法



AutoMapper问题#3962已关闭并锁定,没有任何解释或解决方案。(事实上,所有AutoMapper问题都是这样处理的。维护人员在这里指导人员。(

为了总结该问题,IMemberConfigurationExpression.Condition接收一个Func<TSrc, TDest, object, bool>。第三个参数是要访问的源成员的值。例如:

public static class IMappingExpressionExtensions
{
public static void Coalesce<Src, Dst>(this IMappingExpression<Src, Dst> exp)
{
exp.ForAllMembers(cfg => cfg.Condition((src, dst, srcMember) => srcMember != null));
}
}

当源成员是引用类型并且其值为null时,srcMember将按预期为null。但是,当源成员是没有值的Nullable<T>时,srcMember意外地是default(T)而不是null。

有变通办法吗?

问题的核心是在源成员转换为目标成员类型后调用Condition。这就是为什么Condition对于引用类型,甚至对于Nullable<T>Nullable<T>,但对于Nullable<T>T,都能按预期工作。

如果TSrc的所有属性都映射到具有相同名称的TDst的属性,则以下解决方案将完全替换Condition,从而产生供参考的预期行为,Nullable<T>Nullable<T>,以及Nullable<T>T。尽管涉及反思和拳击,但它似乎相当快。

public static void Coalesce<TSrc, TDst>(this IMappingExpression<TSrc, TDst> mapExp)
{
foreach (var srcProp in typeof(TSrc).GetProperties())
{
mapExp.ForMember(srcProp.Name, mapExp => mapExp.PreCondition((o, _) => srcProp.GetValue(o) != null));
}
}

如果这对您不起作用,并且您可以将所有映射的Nullable<T>映射更改为T,则可以将<T?,T>的默认类型转换器替换为";转换";将空CCD_ 23转换为目的地值。

public class CoalescingTypeConverter<T> : ITypeConverter<T?, T> where T : struct
{
public T Convert(T? source, T destination, ResolutionContext context)
{
return source ?? destination;
}
}
public static class IMapperConfigurationExpressionExtensions
{
public static void CoalesceNullable<T>(this IMapperConfigurationExpression cfg) where T : struct
{
cfg.CreateMap<T?, T>().ConvertUsing<CoalescingTypeConverter<T>>();
}
}
services.AddAutoMapper(cfg =>
{
cfg.CoalesceNullable<int>();
cfg.CoalesceNullable<bool>();
// etc.
}

最新更新