AutoMapper and flattening nested arrays

前端 未结 3 1151
傲寒
傲寒 2020-12-09 00:31

I\'m trying to use AutoMapper to flatten multiple levels of arrays.

Consider the following source classes:

class X {
    public string A { get; set;         


        
3条回答
  •  心在旅途
    2020-12-09 00:51

    I had a very similar problem a while ago. I had a collection of locations, and each location had a collection of streets. I wanted to map them to a collection of view models where each view model represented a street (including the location details).

    This was my solution: https://groups.google.com/forum/#!topic/automapper-users/b66c1M8eS8E

    For this particular problem, this could be your mapping configuration:

    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());
         }
    }
    

    Because AutoMapper is primarily a 1:1 mapping, you need to implement a wee bit of magic to map to multiple objects. This is an example of how you could call that mapping to populate your object:

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

    Here are a couple of unit tests to validate the mapping and show it in action:

    [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 => x.B.SelectMany(
                    y => y.D
                        .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 => x.F == "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"));
        }
    }
    

提交回复
热议问题