2016-10-27 3 views
2

Я пытаюсь использовать AutoMapper для unflatten объекта.AutoMapper: Карта для коллекции из нескольких исходных свойств

У меня есть источник следующим

public class Source 
{ 
    public string Name {get;set;} 
    public string Child1Property1 {get;set;} 
    public string Child1Property2 {get;set;} 
    public string Child2Property1 {get;set;} 
    public string Child2Property2 {get;set;} 
} 

Я хочу, чтобы сопоставить это по назначению

public class Destination 
{ 
    public string Name {get;set;} 
    public List<Child> Children {get;set;} 
} 

public class Child 
{ 
    public string Property1 {get;set;} 
    public string Property2 {get;set;} 
} 

Моя конфигурация отображения

public static class AutoMapperConfiguration 
{ 
    public static MapperConfiguration Configure() 
    { 
     var config = new MapperConfiguration(
      cfg => 
      { 
       cfg.CreateMap<Source, Destination>() 
        .ForMember(dest => dest.Children, /* What do I put here?*/)) 
       // I don't think this is correct 
       cfg.CreateMap<Source, Child>() 
        .ForMember(dest => dest.Property1, opt => opt.MapFrom(src => src.Child1Property1)) 
        .ForMember(dest => dest.Property2, opt => opt.MapFrom(src => src.Child1Property2)) 
        .ForMember(dest => dest.Property1, opt => opt.MapFrom(src => src.Child2Property1)) 
        .ForMember(dest => dest.Property2, opt => opt.MapFrom(src => src.Child2Property2)); 

      }); 
     return config; 
    } 
} 

Теперь, когда я проверить свой код я получаю используя mapper.Map<List<Child>>(source) Я получаю AutoMapperMappingException: Missing type map configuration or unsupported mapping. Что имеет смысл, так как нет отображения c onfigured до List<Child>. Если я делаю mapper.Map<Child>(source), я получаю экземпляр Child со всеми значениями null для свойств.

Я, к сожалению, не в состоянии изменить класс Source.

Возможно ли это вообще с помощью AutoMapper? и если да, то как?

ответ

0

Вы можете добавить метод в класс Source, чтобы получить дочерний список. Тогда его очень легко сопоставить.

+2

Просьба привести краткий пример – liorsolomon

1

Есть как минимум 2 варианта. Вы можете использовать простой метод расширения, чтобы упростить сопоставление, или вы можете создать настраиваемый конвертер типов.

public class ConvertSourceToDestination : ITypeConverter<Source, Destination> 
{ 
    public Destination Convert(Source source, Destination destination, ResolutionContext context) 
    { 
     destination = destination ?? new Destination(); 
     destination.Children = destination.Children ?? new List<Child>(); 
     destination.Children.Add(new Child() { Property1 = source.Child1Property1, Property2 = source.Child1Property2 }); 
     destination.Children.Add(new Child() { Property1 = source.Child2Property1, Property2 = source.Child2Property2 }); 
     destination.Name = source.Name; 

     return destination; 
    } 
} 

public static class SourceExtension 
{ 
    public static IEnumerable<Child> Children(this Source source) 
    { 
     yield return new Child() { Property1 = source.Child1Property1, Property2 = source.Child1Property2 }; 
     yield return new Child() { Property1 = source.Child2Property1, Property2 = source.Child2Property2 }; 
    } 

    public static MapperConfiguration CreateMapping() 
    { 
     var config = new MapperConfiguration(
      cfg => 
      { 
       cfg.CreateMap<Source, Destination>() 
       .ForMember(dest => dest.Children, opt => opt.MapFrom(src => src.Children())); 
      }); 

     return config; 
    } 

    public static MapperConfiguration CreateMapping2() 
    { 
     var config = new MapperConfiguration(
      cfg => 
      { 
       cfg.CreateMap<Source, Destination>().ConvertUsing(new ConvertSourceToDestination()); 

      }); 

     return config; 
    } 
}