AutoMapper和展平嵌套数组

我正在尝试使用AutoMapper来压缩多个级别的数组。

考虑以下源类:

class X { public string A { get; set; } public Y[] B { get; set; } } class Y { public string C { get; set; } public Z[] D { get; set; } } class Z { public string E { get; set; } public string F { get; set; } } 

以下目的地:

 class Destination { public string A { get; set; } public string C { get; set; } public string E { get; set; } public string F { get; set; } } 

我希望能够做的是从一个或多个X获取一个List,例如:

 Mapper.Map<IEnumerable, IEnumerable>(arrayOfX); 

我无法弄清楚用什么类型的映射配置来实现这一目标。 MapFrom似乎是1:1合成的方式,但似乎无法处理数组(或其他可枚举),除非我使用AutoMapper的目标命名约定。

有关如何实现这一目标的任何见解?

试试这个映射器,

 Mapper.CreateMap(); Mapper.CreateMap(); Mapper.CreateMap() .ForMember(destination => destination.A, options => options.MapFrom(source => source.A)).IgnoreAllNonExisting() .ForMember(destination => destination.C, options => options.MapFrom(source => Mapper.Map, IEnumerable>(source.B).FirstOrDefault().C)) .ForMember(destination => destination.E, options => options.MapFrom(source => Mapper.Map, IEnumerable>(source.B.SelectMany(d => dD)).FirstOrDefault().E)) .ForMember(destination => destination.F, options => options.MapFrom(source => Mapper.Map, IEnumerable>(source.B.SelectMany(d => dD)).FirstOrDefault().F)); var result = Mapper.Map, IEnumerable>(arrayOfX); 

我刚才有一个非常类似的问题。 我收集了一些地点,每个地点都有一系列街道。 我想将它们映射到一组视图模型,其中每个视图模型代表一条街道(包括位置详细信息)。

这是我的解决方案: https : //groups.google.com/forum/#!topic /automapper-users / b66c1M8eS8E

对于这个特殊问题,这可能是您的映射配置:

 public static class AutoMapperConfig { public static void Configure() { Mapper.CreateMap() .ForMember(dest => dest.A, opt => opt.Ignore()) .ForMember(dest => dest.C, opt => opt.Ignore()); Mapper.CreateMap() .ForMember(dest => dest.A, opt => opt.Ignore()) .ForMember(dest => dest.E, opt => opt.Ignore()) .ForMember(dest => dest.F, opt => opt.Ignore()); Mapper.CreateMap() .ForMember(dest => dest.C, opt => opt.Ignore()) .ForMember(dest => dest.E, opt => opt.Ignore()) .ForMember(dest => dest.F, opt => opt.Ignore()); } } 

由于AutoMapper主要是1:1映射,因此您需要实现一点魔法来映射到多个对象。 这是一个如何调用该映射来填充对象的示例:

 var rc = data.SelectMany( x => xBSelectMany( y => yD .Select(Mapper.Map) .Select(z => Mapper.Map(y, z)) ) .Select(y => Mapper.Map(x, y)) ); 

以下是一些unit testing,用于validation映射并将其显示在行动中:

 [TestFixture] public class MapperTests { [Test] public void Mapping_Configuration_IsValid() { AutoMapperConfig.Configure(); Mapper.AssertConfigurationIsValid(); } [Test] public void Mapping_TestItems_MappedOK() { AutoMapperConfig.Configure(); Mapper.AssertConfigurationIsValid(); var data = new[] { new X { A = "A1", B = new[] { new Y { C = "A1C1", D = new[] { new Z { E = "A1C1E1", F = "A1C1F1" }, new Z { E = "A1C1E2", F = "A1C1F2" }, } }, new Y { C = "A1C2", D = new[] { new Z { E = "A1C2E1", F = "A1C2F1" }, new Z { E = "A1C2E2", F = "A1C2F2" }, } } } } }; var rc = data.SelectMany( x => xBSelectMany( y => yD .Select(Mapper.Map) .Select(z => Mapper.Map(y, z)) ) .Select(y => Mapper.Map(x, y)) ); Assert.That(rc, Is.Not.Null); Assert.That(rc.Count(), Is.EqualTo(4)); var item = rc.FirstOrDefault(x => xF == "A1C2F2"); Assert.That(item, Is.Not.Null); Assert.That(item.A, Is.EqualTo("A1")); Assert.That(item.C, Is.EqualTo("A1C2")); Assert.That(item.E, Is.EqualTo("A1C2E2")); Assert.That(item.F, Is.EqualTo("A1C2F2")); } }