【问题标题】:Automapper (C#): Nested mappings not workingAutomapper (C#):嵌套映射不起作用
【发布时间】:2011-03-24 15:06:51
【问题描述】:

我有一个简单的映射,它正在工作,但它没有填写 Output.Details。

我有点困惑,我想这可能是因为我将源用作每个任务的“任务”。

  Mapper.CreateMap<Task, Output>();


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

据我所知,我必须创建 2 个地图,1 个用于对象,1 个用于其中包含的对象。

问题是 OUTPUT 的来源,OUTPUT.DETAILS 可以在 TASK 中找到

我尝试深入研究第一个地图中的详细信息并指定 Mapfrom,但它给出了以下错误,这就是我必须创建 2 个地图的原因

         must resolve to top-level member. Parameter name: lambdaExpression error

  IList<Task> tempItems= GetItems();

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

地图有效,但我在 Output.Details 中可用的属性“项目”为 NULL

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

它填写 Name 没问题,但 DETAILS 里面什么都没有......它们被保留为 NULL。

Task 不是我的课,但我检查了它,所有值都可以复制,因此 Tag 有一个值并且是一个 STRING。

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类的例子。

编辑

他们是这里的一个示例 vs 2010 项目,它准确地显示了问题。

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

这是显示问题的图像,您可以看到摘要项为“NULL”,但它应该包含来自任务的名称。

【问题讨论】:

  • 任务是什么样的?你可以为Task定义类吗?你的输出构造函数中的“属性”是什么?它不会出现在课堂上的任何地方。
  • 嗨帕特里克,非常感谢您的回复。属性是一个错字:-) 抱歉,它的摘要实际上.. 它创建了实例.. 我更新了问题,并且我还包含了任务的图像.. 任务不是我的课程
  • 您希望 Output.Summary 包含什么?您没有为它设置 Ignore() ,但 Task 没有 Summary 属性?现在,由于您没有有效的映射配置开始,因此很难提供帮助。有什么方法可以创建一个临时任务类来重现您遇到的特定问题?
  • 嗨帕特里克,它的工作到目前为止 Output.Name 是从 Task.Name 中填充的,这是因为 Name 和 Name 存在于每个类 Task 和 Output 中,所以我不需要 MapFrom...他们匹配。 Output.Details.Name 未填写。它的NULL ...我正在尝试从Task.Name中填充它(作为测试)......因此它们不匹配所以我正在做一个MapFrom Task.Name >>>>> Output.Details.Name。这有帮助吗?我的输出类有 Output.Name 和 Output.Details 但是在 Output.Details 里面的 Name 是 = null ...没有发生映射。
  • 我什至通过将 MapFrom 更改为 ResolveUsing 并设置解析器并在其中放置断点来确认这一点......它永远不会进入......

标签: c# automapper inner-classes


【解决方案1】:

首先,始终使用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();

这就是你所需要的。

【讨论】:

  • 哇,帕特里克!是的,我总是包含断言,但构建我忘记的示例应用程序.. 哎呀!这很好用,但我有点困惑。在文档automapper.codeplex.com/… 上,它声明我需要创建 2 个地图。1 个用于任务、输出,另一个用于 Output.Details。你发给我的东西很好用!但你它正在动态创建课程。
  • 根据此处的示例automapper.codeplex.com/…(如果它没有过时!一定是它对我不起作用:-))它声明我创建了 2 个地图.. 1 用于外部和 1对于内部...这正是我正在做的不是吗..我有一个外部和一个内部?那么设置2张地图并做地图应该可以吗?
  • 感谢您在这方面的坚持,您提供的任何帮助让我理解为什么它不能按照 codeplex 示例工作将非常有帮助
  • 在 codeplex 示例中,source 和 dest 上的内部类的属性名称相同。事实上,两者的整体类结构是相同的。使用相同的属性名称,Automapper 将检查它是否知道如何从源类型转换为目标类型(在示例中,它确实知道)。你没有相同的设置。您有一个平面类(任务),您希望将其映射到一个类以及该类的成员(Automapper 并不真正支持的一对多)。
  • 哇,感谢帕特里克一直支持我,!我现在明白了很多。
【解决方案2】:

对于新版本,可以如下执行:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-17
    • 1970-01-01
    • 2022-01-06
    • 2017-07-20
    • 2020-02-04
    • 1970-01-01
    • 1970-01-01
    • 2020-12-12
    相关资源
    最近更新 更多