AutoMapper能否从Dictionary<string, object>映射到派生/运行时属性类型?
AutoMapper支持从Dictionary<string, object>映射到对象图,也支持运行时多态的映射继承,但不清楚如何处理目标对象属性以基类声明,但运行时是派生实例,且要映射的属性仅存在于派生类的场景。
尝试过创建Dictionary<string, object>到基类Base和派生类Derived的映射,并用Include/IncludeAllDerived配置,但都未成功——这些配置主要针对源类型有继承层次的场景,不适用字典这种动态松散的源。
单独映射派生实例本身是正常的(调用mapper.Map(propertyImport, propertyDestination)可以成功),但当通过父对象(SomeObjectWithAProperty)映射时就会失败,因为AutoMapper只认Base的声明属性,忽略了运行时的Derived类型。
我们无法提前知道字典里的属性,也不知道哪些属性是运行时派生类型,目标是让AutoMapper根据属性的运行时类型自动映射,不受声明类型限制。
调用mapper.Map(objectImport, objectDestination)时抛出异常:
AutoMapper.AutoMapperMappingException: Error mapping types.
Mapping types:
Dictionary`2 -> SomeObjectWithAProperty
[...]
---> System.ArgumentOutOfRangeException: Cannot find member Baz of type UserQuery+Base. (Parameter 'name')
复现代码(可在LinqPad或控制台应用运行)
void Main() { var objectDestination = new SomeObjectWithAProperty { SomeProperty = new Derived(100m, 10, "bar"), }; var propertyDestination = objectDestination.SomeProperty; var objectImport = new Dictionary<string, object> { ["SomeProperty.Foo"] = 123, ["SomeProperty.Bar"] = "blah", ["SomeProperty.Baz"] = 200m, }; var propertyImport = new Dictionary<string, object> { ["Foo"] = 123, ["Bar"] = "blah", ["Baz"] = 200m, }; var mapper = new MapperConfiguration(mc => { //mc.CreateMap<Dictionary<string, object>, Base>().IncludeAllDerived(); //mc.CreateMap<Dictionary<string, object>, Derived>(); //mc.CreateMap<Dictionary<string, object>, Base>() // .IncludeAllDerived(); //mc.CreateMap<Dictionary<string, object>, Base>() // .Include<Dictionary<string, object>, Derived>(); }).CreateMapper(); mapper.Map(propertyImport, propertyDestination); mapper.Map(objectImport, objectDestination); } public class SomeObjectWithAProperty { public Base SomeProperty { get; set; } } public record Base(int Foo, string Bar); public record Derived(decimal Baz, int Foo, string Bar) : Base(Foo, Bar);
内容的提问来源于stack exchange,提问作者MicrosoftStackDev

