2014-11-10 2 views
3

Рассмотрим эти классы в качестве источника:Сведение без префиксами имен дочернего объекта в AutoMapper

public class SourceParent 
{ 
    public int X { get; set; } 
    public SourceChild1 Child1 { get; set; } 
    public SourceChild2 Child2 { get; set; } 
} 

public class SourceChild1 
{ 
    public int A { get; set; } 
    public int B { get; set; } 
    public int C { get; set; } 
    public int D { get; set; } 
} 

public class SourceChild2 
{ 
    public int I { get; set; } 
    public int J { get; set; } 
    public int K { get; set; } 
    public int L { get; set; } 
} 

Я пытаюсь отобразить источник в пункт назначения, подобный следующему:

public class Destination 
{ 
    public int X { get; set; } 

    public int A { get; set; } 
    public int B { get; set; } 
    public int C { get; set; } 
    public int D { get; set; } 

    public int I { get; set; } 
    public int J { get; set; } 
    public int K { get; set; } 
    public int L { get; set; } 
} 

Ну, используя эту конфигурацию можно сделать:

Mapper.CreateMap<SourceParent, Destination>() 
    .ForMember(d => d.A, opt => opt.MapFrom(s => s.Child1.A)) 
    .ForMember(d => d.B, opt => opt.MapFrom(s => s.Child1.B)) 
    .ForMember(d => d.C, opt => opt.MapFrom(s => s.Child1.C)) 
    .ForMember(d => d.D, opt => opt.MapFrom(s => s.Child1.D)) 
    .ForMember(d => d.I, opt => opt.MapFrom(s => s.Child2.I)) 
    .ForMember(d => d.J, opt => opt.MapFrom(s => s.Child2.J)) 
    .ForMember(d => d.K, opt => opt.MapFrom(s => s.Child2.K)) 
    .ForMember(d => d.L, opt => opt.MapFrom(s => s.Child2.L)); 

Кроме того, если у дочернего класса Многие объекты, все из которых имеют одно и то же имя с родителем, это не чистый способ.

В идеале я хотел бы сказать AutoMapper, чтобы в качестве источника взять Source.Child1 и Source.Child2, и сопоставить все соответствующие имена свойств с целью (вместо указания каждого отдельного свойства); что-то вроде этого:

Mapper.CreateMap<SourceParent, Destination>() 
    .AlsoUseSource(s => s.Child1) 
    .AlsoUseSource(s => s.Child2); 

ответ

3

.ConstructUsing Чтобы выполнить это, вы можете использовать .ConstructUsing. Это не самая чистая ищет вещь в мире, но он будет работать:

/* Map each child to the destination */ 
Mapper.CreateMap<SourceChild1, Destination>(); 
Mapper.CreateMap<SourceChild2, Destination>(); 

Mapper.CreateMap<SourceParent, Destination>() 
    .ConstructUsing(src => 
    { 
     /* Map A-D from Child1 */ 
     var dest = Mapper.Map<Destination>(src.Child1); 

     /* Map I-L from Child2 */ 
     Mapper.Map(src.Child2, dest); 

     return dest; 
    }); 
/* X will be mapped automatically. */ 

Это должно успешно отобразить все свойства.

К сожалению, вызов .AssertConfigurationIsValid не получится, так как свойства I - L не будет отображаться на тип назначения для отображения из SourceParentDestination.

Вы можете, конечно, написать номер .Ignore для каждого из них, но это может привести к поражению цели избавления от вложенных вызовов отображения.

Ваш другой вариант - использовать this awesome answer, чтобы игнорировать неизменяемые свойства для каждого из отображений.

+0

Спасибо, это полезно. На самом деле я закончил делать что-то подобное (делая то же самое, используя «AfterMap»). Но я оставлю вопрос без ответа еще на один-два дня, чтобы узнать, есть ли кто-нибудь еще с «более чистым» ответом. – Iravanchi

Смежные вопросы