AutoMapper 在从 C# Dynamic/ExpandoObject

问题描述

我在尝试使用 AutoMapper 将来自数据库(为清楚起见,MongoDB,但我认为这无关紧要)的动态对象映射到特定类时遇到问题。

类继承信息存储在属性 _t 中(由 Mongo 在序列化时完成) - 在创建包含继承的底层对象时,如何指示 AutoMapper 使用 _t 中的类信息?

这是我的班级信息

class Person
{
public string id { get; set; }
public Foo Foo { get; set; }
}
class Foo
{
public string name { get; set; }
public string _t { get; set; }
}
class Bar : Foo
{
public string size { get; set; }
}

我传入的动态对象如下所示:

Person.id = "Bob"
Person.Foo.name = "Bob"
Person.Foo._t = "Bar"
Person.Foo.size = "123"

当我使用 automapper 使用此代码将其映射到 Person 时

        var configuration = new MapperConfiguration(cfg => {});
        var mapper = configuration.CreateMapper();
        Person Person = mapper.Map<Person>(MyDynamic);

生成的 Person.Foo 不是 Bar 类型。我完全理解(为什么)会是这种情况,因为 AutoMapper 不了解原始类是什么。但是考虑到 class 的信息存储在 _t 中,我可以指示 AutoMapper 使用它来确保 Person.Foo 是 Bar 类型吗?

解决方法

您可以通过以下方式实现:

dynamic person = new ExpandoObject();

person.Foo = new ExpandoObject();
person.Foo.name = "Bob";
person.Foo._t = "Bar";
person.Foo.size = "123";

var configuration = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<dynamic,Person>().ConvertUsing((src,dst,ctx) =>
    {
        if (src.Foo._t == "Foo")
        {
            return new Person
            {
                Foo = ctx.Mapper.Map<Foo>(src.Foo)
            };
        }
        else
        {
            return new Person
            {
                Foo = ctx.Mapper.Map<Bar>(src.Foo)
            };
        }
    });
});

var mapper = configuration.CreateMapper();
Person p = mapper.Map<Person>(person);

注意:如果 Foonull,上面的示例不处理这种情况,但应该适用于您在问题中概述的确切问题。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...