且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

当指定条件!= null时,Automapper无法正确映射null列表成员

更新时间:2023-02-09 12:51:59

这应该可以,但是我不确定是否要像这样对它进行微管理:

This should work but I'm not sure if you want to micro manage it like that:

cfg.AllowNullCollections = true;
cfg.CreateMap<GeneralInfo, GeneralInfo>()
    .ForMember(x => x.PersonList, opts => opts.PreCondition((src) => src.PersonList != null));

问题是专门处理的集合(对于大多数映射器都是如此,尽管AutoMapper在这种情况下有点奇怪,这不是我的最爱),并且似乎需要初始化目标集合.正如我所看到的,收集并没有完整地复制,这是有道理的,但是您需要初始化并复制单个项目(这是我的推论,但听起来不错).

Problem is the collections that are handled specifically (that's true for most mappers though AutoMapper is a bit weird in this case, it's not my favorite) and seem to require the destination collection to be initialized. As I can see, collections are not copied in entirety which makes sense, but you need to initialize and copy individual items (this is my deduction but does sound right).

即即使您跳过源,目标仍将最终重新初始化(空).

I.e. even if you skip the source, destination would still end up reinitialized (empty).

问题似乎是Condition,因为文档,在以后的某个时间点应用,此时目的地已经初始化.

Problem as it seems is the Condition which is, given their documentation, applied at some later point, at which time the destination has already been initialized.

PreCondition具有与您期望的方式不同的签名,因为它不采用实际值,仅提供源.

PreCondition on the other hand has a different signature to be used like you intended, as it doesn't take actual values, just source is available.

唯一可行的解​​决方案是使用每个成员" PreCondition(如上所述).

The only solution that seems to work is to use "per member" PreCondition (like the above).

编辑:
...或这个(使用ForAllMembers),但是有点难看,反射等.

EDIT:
...or this (using the ForAllMembers), but a bit ugly, reflection etc.

cfg.CreateMap<GeneralInfo, GeneralInfo>()
.ForAllMembers(opts =>
    {
        opts.PreCondition((src, context) =>
        {
            // we can do this as you have a mapping in between the same types and no special handling
            // (i.e. destination member is the same as the source property)
            var property = opts.DestinationMember as System.Reflection.PropertyInfo;
            if (property == null) throw new InvalidOperationException();
            var value = property.GetValue(src);
            return value != null;
        });
    }
);

...但是似乎对此没有任何更清洁的支持.

...but there doesn't seem to be any cleaner support for this.

编辑(错误和最终想法):

从5.2.0#1918版本起,到现有集合的条件映射不起作用>

Conditional mapping to existing collection doesn't work from version 5.2.0 #1918

正如评论中指出的那样(@LucianBargaoanu),这似乎确实是一个错误,因为在这种拐角"情况下并不一致(尽管我不同意,这是一个非常典型的场景)收集并传递目的地.在这种情况下,由于目的地已经被初始化/清除,因此Condition几乎没有用.

As pointed out in the comment (by @LucianBargaoanu), this seems to be a bug really, as it's inconsistent in this 'corner' case (though I wouldn't agree on that, it's a pretty typical scenario) when mapping collections and passing the destination. And it pretty much renders the Condition useless in this case as the destination is already initialized/cleared.

确实唯一的解决方案似乎是PreCondition(但是由于签名不同而存在问题,我个人不确定为什么它们也不会将相同的过多参数传递给PreCondition? ).

The only solution indeed seems to be the PreCondition (but it has issues given the different signature, I'm personally not sure why they don't pass the same plethora of parameters into the PreCondition as well?).

还有更多信息:

相关代码(我认为)

使用条件"但未忽略#1940时巢嵌套已清除

尽管Condition()返回错误的#2111,但目标对象上的Collection属性仍被覆盖

空源集合清空目标集合#2031