Automapper - Multi object source and one destination

后端 未结 5 1996
情歌与酒
情歌与酒 2020-12-07 22:43

I am using auto mapper to map multiple objects (db class into ui objects).

Map 1:

Mapper.CreateMap().ForMember(sss =>         


        
相关标签:
5条回答
  • 2020-12-07 22:52

    According to me you should avoid calling the overloaded Map method taking an instance of the destination object as explained in the accepted answer. This won't let you test/validate your mapping configuration (Mapper.Configuration.AssertConfigurationIsValid()) or to do so you will add a lot of 'Ignore' in your mappings.

    A very simple solution is to create a composite type holding source references and define your mapping to the destination based on that composite type.

    Something like:

        public class SourceOneTwo
        {
            public SourceOne SourceOne { get; set; }
            public SourceTwo SourceTwo { get; set; }
        }
        static void Main(string[] args)
        {
            var config = new MapperConfiguration(cfg => 
                cfg.CreateMap<SourceOneTwo, Destination>()
                .ForMember(dest => dest.one, m => m.MapFrom(source => source.SourceOne.abc))
                .ForMember(dest => dest.two, m => m.MapFrom(source => source.SourceTwo.xyz)));
            config.AssertConfigurationIsValid();
        }
    
    0 讨论(0)
  • 2020-12-07 22:55

    Nowadays it looks like that:

    DestinationDto = _mapper.Map(source2, _mapper.Map<source1type, destinationType>(source1));
    
    0 讨论(0)
  • 2020-12-07 23:05
    public class Person
    {
        public string Name { get; set; }
        public string PhNo { get; set; }
    }
    public class Company
    {
        public int EmpNo { get; set; }
        public string Title { get; set; }
    }
    
    public class PersonCompany
    {
        public string Name { get; set; }
        public string PhNo { get; set; }
    
        public int EmpNo { get; set; }
        public string Title { get; set; }
    }
    
    //you can test as below
            var pMap = Mapper.CreateMap<Person,PersonCompany>();
            pMap.ForAllMembers(d => d.Ignore()); 
            pMap.ForMember(d => d.Name, opt => opt.MapFrom(s => s.Name))
                .ForMember(d => d.PhNo, opt => opt.MapFrom(s => s.PhNo));
    
            var cMap = Mapper.CreateMap<Company, PersonCompany>();
            cMap.ForAllMembers(d => d.Ignore());
            cMap.ForMember(d => d.EmpNo, opt => opt.MapFrom(s => s.EmpNo))
                .ForMember(d => d.Title, opt => opt.MapFrom(s => s.Title));
    
    
            var person = new Person { Name = "PersonName", PhNo = "212-000-0000" };
            var personCompany = Mapper.Map<Person,PersonCompany>(person);
            var company = new Company { Title = "Associate Director", EmpNo = 10001 };
            personCompany = Mapper.Map(company, personCompany);
    
            Console.WriteLine("personCompany.Name={0}", personCompany.Name);
            Console.WriteLine("personCompany.PhNo={0}", personCompany.PhNo);
            Console.WriteLine("personCompany.EmpNo={0}", personCompany.EmpNo);
            Console.WriteLine("personCompany.Title={0}", personCompany.Title);
    
    0 讨论(0)
  • 2020-12-07 23:06
    mapper.MergeInto<PersonCar>(person, car)
    

    with the accepted answer as extension-methods, simple and general version:

    public static TResult MergeInto<TResult>(this IMapper mapper, object item1, object item2)
    {
        return mapper.Map(item2, mapper.Map<TResult>(item1));
    }
    
    public static TResult MergeInto<TResult>(this IMapper mapper, params object[] objects)
    {
        var res = mapper.Map<TResult>(objects.First());
        return objects.Skip(1).Aggregate(res, (r, obj) => mapper.Map(obj, r));
    }
    

    after configuring mapping for each input-type:

    IMapper mapper = new MapperConfiguration(cfg =>
    {
        cfg.CreateMap<Person, PersonCar>();
        cfg.CreateMap<Car, PersonCar>();
    }).CreateMapper();
    
    0 讨论(0)
  • 2020-12-07 23:12

    Map has an overload that takes a source and destination object:

    d = AutoMapper.Mapper.Map<sourceone, destination>(sourceone);
    
    /* Pass the created destination to the second map call: */
    AutoMapper.Mapper.Map<sourcetwo, destination>(sourcetwo, d);
    
    0 讨论(0)
提交回复
热议问题