使用Automapper映射两个Collection时如何使用BeforeMap Action?

时间:2019-04-24 11:23:47

标签: c# automapper

使用自动映射器映射两个单个对象时,BeforeMap动作可以正常工作:

return _mapper.Map<Project, ProjectDto>(projects, opt =>
{
    opt.BeforeMap((src, dest) => dest.ProvidedLanguage = requestedLanguage);
});

但是在映射两个集合时,BeforeMap不能像src那样工作,而dest的类型现在是object

return _mapper.Map<IEnumerable<Project>, IEnumerable<ProjectDto>>(projects, opt =>
{
    opt.BeforeMap((src, dest) => dest.ProvidedLanguage = requestedLanguage);
});

我需要映射本身提供的语言,因此无法在映射后进行设置。映射两个集合时如何将提供的语言传递给目标对象?

2 个答案:

答案 0 :(得分:1)

我初步解决了这个问题:

        var result = new List<ProjectDto>();
        foreach (var item in projects)
        {
            var dest = new ProjectDto() { ProvidedLanguage = requestedLanguage };
            result.Add(_mapper.Map(item, dest));
        }

我知道,它看起来并不优雅。如果有人知道解决问题的更好方法,请随时分享您的想法。

答案 1 :(得分:0)

使用BeforeMap()调整目标对象很危险。运行代码:

return _mapper.Map<Project, ProjectDto>(projects, opt =>
{
    opt.BeforeMap((src, dest) => dest.ProvidedLanguage = requestedLanguage);
});

将导致NullReferenceException,因为dest对象尚未由AutoMapper初始化。请注意,BeforeMap()最适合对 source 对象执行一些调整,因为对目标对象的任何工作都可以被即将到来的映射过程覆盖。如果要调整目标对象,最好使用AfterMap()。这样,您将完成映射过程,并确定已初始化目标对象。我并不是说您不应该使用BeforeMap(),而是要谨慎使用它,并在您真正知道自己在做什么时使用它。

在映射集合时,它们似乎是object类型,但事实就是如此。在调试器中放置一个断点,以查看其类型正确。

您将无法在ProvidedLanguage上设置IEnumerable属性。如果要在ProjectDto内的每个IEnumerable上设置该属性,请为此使用foreach循环:

return _mapper.Map<IEnumerable<Project>, IEnumerable<ProjectDto>>(projects, opt =>
{
    opt.AfterMap((source, destination) =>
    {
        foreach (var dto in destination)
        {
            dto.ProvidedLanguage = requestedLanguage;
        }
    });
});