miałem bardzo podobny problem jakiś czas temu. Miałem kolekcję lokacji, a każda lokalizacja miała kolekcję ulic. Chciałem je zmapować do kolekcji modeli widoków, gdzie każdy model widoku reprezentował ulicę (w tym szczegóły lokalizacji).
To było moje rozwiązanie: https://groups.google.com/forum/#!topic/automapper-users/b66c1M8eS8E
Dla tego konkretnego problemu, może to być konfiguracja mapowania:
public static class AutoMapperConfig
{
public static void Configure()
{
Mapper.CreateMap<Z, Destination>()
.ForMember(dest => dest.A, opt => opt.Ignore())
.ForMember(dest => dest.C, opt => opt.Ignore());
Mapper.CreateMap<Y, Destination>()
.ForMember(dest => dest.A, opt => opt.Ignore())
.ForMember(dest => dest.E, opt => opt.Ignore())
.ForMember(dest => dest.F, opt => opt.Ignore());
Mapper.CreateMap<X, Destination>()
.ForMember(dest => dest.C, opt => opt.Ignore())
.ForMember(dest => dest.E, opt => opt.Ignore())
.ForMember(dest => dest.F, opt => opt.Ignore());
}
}
Ponieważ AutoMapper to przede wszystkim 1: 1 mapowanie, trzeba zaimplementować odrobinę magii, aby odwzorować na wiele obiektów. Jest to przykład tego, jak można nazwać to odwzorowanie aby wypełnić swój obiekt:
var rc = data.SelectMany(
x => x.B.SelectMany(
y => y.D
.Select(Mapper.Map<Z, Destination>)
.Select(z => Mapper.Map(y, z))
)
.Select(y => Mapper.Map(x, y))
);
Oto kilka testów jednostkowych do sprawdzania poprawności odwzorowania i pokazać go w akcji:
[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<Z, Destination>)
.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"));
}
}
To wygeneruje AutoMapperMappingException, jeśli B lub D jest tablicą zerową lub zerową. X [] arrayOfX = nowy X [] {nowy X() {A = "a1", B = null}, nowy X() {A = "a2", B = nowy Y [] {}}}; –
@JayWalker Edytowałem mój wpis. Właśnie dodano kontrolę zerową. Dzięki za znalezienie. –