Automapper(C#):嵌套映射无法正常工作

4

我有一个简单的映射,它可以工作,但是它没有填充Output.Details。

我有点困惑,我认为这可能是因为我为每个源都使用了“任务”。

  Mapper.CreateMap<Task, Output>();


  Mapper.CreateMap<Task, Output.Details>().ForMember(
       dest => dest.Item, opt => opt.MapFrom(src => src.Name));

据我所知,我需要创建两个地图,一个用于对象,另一个用于包含其中的对象。
问题是输出和输出详细信息的来源可以在任务中找到。
我尝试深入第一个地图中的详细信息,并指定Mapfrom,但它会出现以下错误,这就是为什么我必须创建两个地图的原因。
         must resolve to top-level member. Parameter name: lambdaExpression error

  IList<Task> tempItems= GetItems();

        IList<Output> items =
            Mapper.Map<IList<Task>, IList<Output>>(tempItems);

地图可以使用,但是我的属性“Item”在Output.Details中不可用,即为NULL。

我做错了什么?这是我的目标对象。

它可以填写名称,但是DETAILS内部没有任何内容...它们都为空。

Task不是我的类,但我已经检查过了,所有值都可以被复制,因此Tag具有值并且是一个字符串。

public class Output   
{
    public string Name { get; set; }

    public Details Summary { get; private set; }
 
    public class Details
    {
        public string Item{ get; set; }
    }

    public Output()
    {
        Summary = new Details();
    }
}

编辑

这里是Task类的一个示例。

enter image description here

编辑

这里有一个示例vs 2010项目,它清楚地显示了问题。

http://dl.dropbox.com/u/20103903/AutomapperNotWorking.zip

这里是一个显示问题的图像,您可以看到Summary Item为“NULL”,但它应该包含Task的名称。

enter image description here


嗨,Patrick,非常感谢您的回复。Properties 是一个打字错误 :-) 抱歉,实际上应该是 Sumary.. 它创建了实例.. 我更新了问题,并且还包括了任务的图像.. 任务不是我的类。 - Martin
让我们以这样的一个例子为例,如果我有Task.Name和Task.Details和Task.Details.Name,然后Output.Name和Output.Details和Output.Details.Name-肯定会工作,因为一切都匹配...我的问题是我有一个扁平文件(任务),我需要填充我的输出,它有一个嵌套类型...但我需要从任务中填充。扁平文件>嵌套类型...我知道我在做一些愚蠢的事情...但当我进行断言映射配置时,它不会给我错误。 - Martin
嗨Patrick,感谢您一直陪伴我,是的,该死的错别字!我本来想说“详细信息”,而不是“摘要”。好的Patrick,我将创建一个Visual Studio 2010项目,并稍后上传示例。再次感谢...我现在必须离开,但我会回来的...大约4个小时后我会上传它...再次感谢。 - Martin
嗨Patrick,我上传了一个真实的项目。我创建了自己的Task,因为正如我所解释的那样,这不是我的Class。但是,即使使用我的"MOCK"类,它也显示错误。也就是说,ITEM = null,但ITEM = TASK中的NAME。 - Martin
很抱歉,我无法查看或处理您之前的消息中的链接。请提供其他文本内容,以便我可以为您进行翻译。 - Martin
显示剩余7条评论
2个回答

5
首先,始终使用Mapper.AssertConfigurationIsValid();确保您的映射配置有效。我将其添加到您的代码中,它立即突出显示了问题:您没有告诉Automapper如何处理Summary属性。由于Task不包含名为Summary的属性,因此Automapper需要知道该如何处理它。
因此,问题并不是如何映射嵌套类,而只需告诉Automapper如何处理Summary即可。以下是适用于您示例的Automapper配置:
Mapper.CreateMap<Task, Output>()
    .ForMember(d => d.Summary, o => o.MapFrom(t => new Output.Details {Item = t.Name}));
Mapper.AssertConfigurationIsValid();

这就是你所需要的。


感谢您一直陪伴我,如果您能帮助我理解为什么它不能按照CodePlex示例正常工作,那将非常有帮助。 - Martin
1
在CodePlex的示例中,源和目标内部类的属性名称相同。 实际上,两者的整体类结构是相同的。 使用相同的属性名称,Automapper将检查是否知道如何从源类型转换为目标类型(在示例中,它确实知道)。 您没有相同的设置。 您有一个平面类(任务),您希望将其映射到类以及该类的成员(一种Automapper不真正支持的1对多)。 - PatrickSteele
哇,感谢Patrick一直陪伴我解决这个问题!现在我对它的理解更深了。 - Martin

0

对于新版本,可以按照以下步骤执行:

var config = new MapperConfiguration(cfg => {
    cfg.CreateMap<UdtDevQuestion, QuestionViewModel>();
});
config.AssertConfigurationIsValid();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接