0

尝试从 v4.2 升级到 AutoMapper 5.1 并发现集合在运行时未映射 - 源对象在集合中有项目,但映射的目标属性为空。

在 4.2 下,使用相同的映射配置,一切都按预期工作(除了 CreateMap() ctor 中的 MemberList.None)

我有这样的 DTO

public class GeographicEntity
{
 ...
}

public class County : GeographicEntity
{
    ...
}

public class State : GeographicEntity
{
    public List<County> Counties { get; } = new List<County>();
}

像这样的视图模型

public class GeographicEntityViewModel
{
  ...
}

public class CountyViewModel : GeographicEntityViewModel
{
  ...
}

public class StateViewModel : GeographicEntityViewModel
{
    public List<CountyViewModel> Counties { get; } = new List<CountyViewModel>();
}

像这样映射确认

Mapper.Initialize(configuration =>
{
  configuration.CreateMap<GeographicEntity, GeographicEntityViewModel>(MemberList.None);

  configuration.CreateMap<County, CountyViewModel>(MemberList.None)
    .IncludeBase<GeographicEntity, GeographicEntityViewModel>();

  configuration.CreateMap<State, StateViewModel>(MemberList.None)
    .IncludeBase<GeographicEntity, GeographicEntityViewModel>();
});

在 Mapper.Map<> 调用之后,StateViewModel 的 Counties 集合为空(包含 0 个项目的列表),即使源对象的 .Counties 集合中有项目:

var st = new State()
... (initialize the state, including the .Counties list)
var stateViewModel = Mapper.Map<StateViewModel>(st);

任何线索将不胜感激!

4

1 回答 1

0

经过一番挖掘,事实证明 AutoMapper 5 升级引入了一些重大变化。具体来说,在像我这样的目标集合有 getter 但没有 setter 的情况下,行为已经改变。在 AutoMapper 4 中,默认行为是默认使用目标属性,而不是尝试创建新实例。AutoMapper 5 默认不这样做。

解决方案是告诉 AutoMapper 明确使用目标值:

.ForMember(dest => dest.Counties, o => o.UseDestinationValue())

我确信引入这样的重大更改是有充分理由的,但是当您实现了一个广泛的模式并且现在必须寻找并修复可能受此更改影响的每个映射对象时,它会导致无穷无尽的心痛。

我几乎很想放弃升级并坚持使用 Automapper 4.2,因为它完全符合我的需要,无需大量额外和不必要的配置。

更多详情请参考https://github.com/AutoMapper/AutoMapper/issues/1599

于 2016-11-14T20:57:56.110 回答