рд╣рдо рд╕реНрд╡рдпрдВ рдХреЗ рд▓рд┐рдП рдСрдЯреЛрдореИрдкрд░ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ

AutoMapper рдПрдВрдЯрд░рдкреНрд░рд╛рдЗрдЬрд╝ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдореБрдЦреНрдп рдЙрдкрдХрд░рдгреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдпреВрдирд┐рдЯ рдореИрдкрд┐рдВрдЧ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реБрдП рдпрдерд╛рд╕рдВрднрд╡ рдХрдо рдХреЛрдб рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред


рдореБрдЭреЗ рд╡рд┐рд╕реНрддреГрдд рдЕрдиреБрдорд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде MapFrom рдореЗрдВ рджреЛрд╣рд░рд╛рд╡ рдкрд╕рдВрдж рдирд╣реАрдВ рд╣реИред


CreateMap<Pupil, PupilDto>() .ForMember(x => x.Name, s => s.MapFrom(x => x.Identity.Passport.Name)) .ForMember(x => x.Surname, s => s.MapFrom(x => x.Identity.Passport.Surname)) .ForMember(x => x.Age, s => s.MapFrom(x => x.Identity.Passport.Age)) .ForMember(x => x.Number, s => s.MapFrom(x => x.Identity.Passport.Number)) 

рдореИрдВ рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛:


 CreateMap<Pupil, PupilDto>() .From(x=>x.IdentityCard.Passport).To() 

ProjectTo


AutoMapper рджреЛрдиреЛрдВ рдореЗрдореЛрд░реА рдореЗрдВ рдореИрдкрд┐рдВрдЧ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ SQL рдореЗрдВ рдЯреНрд░рд╛рдВрд╕рд▓реЗрдЯ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдХреЛ рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЖрдк рдкреНрд░реЛрдлрд╛рдЗрд▓ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдирд┐рдпрдореЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░ DTO рдореЗрдВ рдкреЗрд╢ рдХрд░рддреЗ рд╣реИрдВред


 EntityQueryable.Select(dtoPupil => new PupilDto() { Name = dtoPupil.Identity.Passport, Surname = dtoPupil.Identity.Passport.Surname}) 

рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦреА рдЧрдИ рдореИрдкрд┐рдВрдЧ рдХрд╛ 80% рдорд╛рдирдЪрд┐рддреНрд░рдг рд╣реИ рдЬреЛ IQueryble рд╕реЗ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛ рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИред


рдпрд╣ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ:


 public ActionResult<IEnumerable<PupilDto>> GetAdultPupils(){ var result = _context.Pupils .Where(x=>x.Identity.Passport.Age >= 18 && ...) .ProjectTo<PupilDto>().ToList(); return result; } 

рдПрдХ рдШреЛрд╖рдгрд╛рддреНрдордХ рд╢реИрд▓реА рдореЗрдВ, рд╣рдордиреЗ рдкреБрдкрд┐рд▓реНрд╕ рдЯреЗрдмрд▓ рдкрд░ рдПрдХ рдХреНрд╡реЗрд░реА рдмрдирд╛рдИ, рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдХреЛ рдЬреЛрдбрд╝рд╛, рд╡рд╛рдВрдЫрд┐рдд рдбреАрдЯреАрдУ рдореЗрдВ рдкреЗрд╢ рдХрд┐рдпрд╛ рдФрд░ рдЗрд╕реЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рджрд┐рдпрд╛, рдЗрд╕рд▓рд┐рдП рдЖрдк рдПрдХ рд╕рд░рд▓ рд╕реАрдЖрд░рдпреВрдбреА рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд╕рднреА рдкрдврд╝реЗ рдЧрдП рддрд░реАрдХреЗ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред рдФрд░ рдпрд╣ рд╕рдм рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реНрддрд░ рдкрд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред


рд╕рдЪ рд╣реИ, рдЧрдВрднреАрд░ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рдРрд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рд╕реЗ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЛ рд╕рдВрддреБрд╖реНрдЯ рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИред


рд╡рд┐рдкрдХреНрд╖ AutoMapper'a


1) рдпрд╣ рдмрд╣реБрдд рд╡реНрдпрд╛рдкрдХ рд╣реИ, "рд╡рд╛рдЗрдб" рдореИрдкрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдЖрдкрдХреЛ рдРрд╕реЗ рдирд┐рдпрдо рд▓рд┐рдЦрдиреЗ рд╣реЛрдВрдЧреЗ рдЬреЛ рдХреЛрдб рдХреА рдПрдХ рдкрдВрдХреНрддрд┐ рдкрд░ рдлрд┐рдЯ рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВред


рдкреНрд░реЛрдлрд╛рдЗрд▓ рдмрдврд╝рддреЗ рд╣реИрдВ рдФрд░ рдХреЛрдб рдХреЗ рдЕрднрд┐рд▓реЗрдЦрд╛рдЧрд╛рд░ рдореЗрдВ рдмрджрд▓ рдЬрд╛рддреЗ рд╣реИрдВ рдЬреЛ рдПрдХ рдмрд╛рд░ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдХреЗрд╡рд▓ рдирд╛рдо рдмрджрд▓рдиреЗ рдкрд░ рд╣реА рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИред


2) рдпрджрд┐ рдЖрдк рдХрдиреНрд╡реЗрдВрд╢рди рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдореИрдкрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдирд╛рдо рдЦреЛ рдЧрдпрд╛ рд╣реИ
DTO рдореЗрдВ рдЧреБрдг:


 public class PupilDto { //  Pupil       IdentityCard // IdentityCard     Passport public string IdentityCardPassportName { get; set; } public string IdentityCardPassportSurname { get; set; } } 

3) рдкреНрд░рдХрд╛рд░ рдХреА рд╕реБрд░рдХреНрд╖рд╛ рдХрд╛ рдЕрднрд╛рд╡


1 рдФрд░ 2 рдЕрдкреНрд░рд┐рдп рдХреНрд╖рдг рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЖрдк рдЙрдирдХреЗ рд╕рд╛рде рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдкрдВрдЬреАрдХрд░рдг рдХрд░рддреЗ рд╕рдордп рдЯрд╛рдЗрдк рд╕реБрд░рдХреНрд╖рд╛ рдХреА рдХрдореА рдХреЗ рд╕рд╛рде, рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрдзрд┐рдХ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ, рдЗрд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:


 // Name - string // Age - int ForMember(x => x.Age, s => s.MapFrom(x => x.Identity.Passport.Name) 

рд╣рдо рд╕рдВрдХрд▓рди рдЪрд░рдг рдореЗрдВ рдРрд╕реА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рди рдХрд┐ рд░рди-рдЯрд╛рдЗрдо рдкрд░ред


рдЗрди рдмрд┐рдВрджреБрдУрдВ рдХреЛ рдЦрддреНрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХреНрд╕рдЯреНрд░реЗрд╢рди рд░реИрдкрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред


рдПрдХ рдЖрд╡рд░рдг рд▓рд┐рдЦрдирд╛


рдкрдВрдЬреАрдХрд░рдг рдЗрд╕ рддрд░рд╣ рдХреНрдпреЛрдВ рд▓рд┐рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП?


 CreateMap<Pupil, PupilDto>() .ForMember(x => x.Name, s => s.MapFrom(x => x.Identity.Passport.Name)) .ForMember(x => x.Surname, s => s.MapFrom(x => x.Identity.Passport.Surname)) .ForMember(x => x.Age, s => s.MapFrom(x => x.Identity.Passport.Age)) .ForMember(x => x.House, s => s.MapFrom(x => x.Address.House)) .ForMember(x => x.Street, s => s.MapFrom(x => x.Address.Street)) .ForMember(x => x.Country, s => s.MapFrom(x => x.Address.Country)) .ForMember(x => x.Surname, s => s.MapFrom(x => x.Identity.Passport.Age)) .ForMember(x => x.Group, s => s.MapFrom(x=>x.EducationCard.StudyGroup.Number)) 

рдЗрддрдирд╛ рдЕрдзрд┐рдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд:


 CreateMap<Pupil,PupilDto>() //    // PassportName = Passport.Name, PassportSurname = Passport.Surname .From(x => x.IdentityCard.Passport).To() // House,Street,Country -   .From(x => x.Address).To() //    -  DTO,  -  .From(x => x.EducationCard.Group).To((x => x.Group,x => x.Number)); 

рдпрджрд┐ рдЖрдкрдХреЛ рдореИрдкрд┐рдВрдЧ рдирд┐рдпрдореЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рд╡рд┐рдзрд┐ рдЯреБрдкрд▓реНрд╕ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░реЗрдЧреА


IMapping <TSource, TDest> рдСрдЯреЛрдореЗрдкрд░ рдХрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИ рдЬрд┐рд╕рдореЗрдВ ForMember, ForAll () рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ... рдпреЗ рд╕рднреА рд╡рд┐рдзрд┐рдпрд╛рдБ рдЗрд╕реЗ (рдзрд╛рд░рд╛рдкреНрд░рд╡рд╛рд╣) рд▓реМрдЯрд╛рддреА рд╣реИрдВред


рд╣рдо рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛ рд╡рд┐рдзрд┐ рд╕реЗ рдпрд╛рдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░реИрдкрд░ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░реЗрдВрдЧреЗ


 public static MapperExpressionWrapper<TSource, TDest, TProjection> From<TSource, TDest, TProjection> (this IMappingExpression<TSource, TDest> mapping, Expression<Func<TSource, TProjection>> expression) => new MapperExpressionWrapper<TSource, TDest, TProjection>(mapping, expression); 

рдЕрдм рдкреНрд░реЛрдЧреНрд░рд╛рдорд░, рдлреНрд░реЙрдо рдореЗрдердб, рд▓рд┐рдЦрд╛ рд╣реБрдЖ, рддреБрд░рдВрдд рдЯреВ- рдореЗрдердб рдХреЗ рдЕрдзрд┐рднрд╛рд░ рдХреЛ рджреЗрдЦреЗрдЧрд╛, рдЬрд┐рд╕рд╕реЗ рд╣рдо рдЙрд╕реЗ рдПрдкреАрдЖрдИ рдмрддрд╛рдПрдВрдЧреЗ, рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╣рдо рд╕рднреА рд╡рд┐рд╕реНрддрд╛рд░ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдЖрдХрд░реНрд╖рдг рдХрд╛ рдПрд╣рд╕рд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдордиреЗ рдСрдЯреЛрдореЛрдЯрд┐рд╡ рд╕реНрд░реЛрддреЛрдВ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦрдиреЗ рдХреЗ рдмрд┐рдирд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд┐рдпрд╛


рд╣рдо рдЯрд╛рдЗрдк рдХрд░рддреЗ рд╣реИрдВ


рдЯрд╛рдЗрдк рдХреА рдЧрдИ рд╡рд┐рдзрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИред


рдЖрдЗрдП рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЛ рдбрд┐рдЬрд╛рдЗрди рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ, рд╣рдореЗрдВ рдЗрд╕реЗ рдпрдерд╛рд╕рдВрднрд╡ рдЯреБрдХрдбрд╝реЛрдВ рдореЗрдВ рддреЛрдбрд╝рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдФрд░ рдЕрдиреНрдп рддрд░реАрдХреЛрдВ рдореЗрдВ рд╕рднреА рддрд░реНрдХ рдХреЛ рдмрд╛рд╣рд░ рдирд┐рдХрд╛рд▓рдирд╛ рдЪрд╛рд╣рд┐рдПред рддреБрд░рдВрдд рд╕рд╣рдордд рд╣реВрдВ рдХрд┐ рд╣рдо рдЯрдкрд▓ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рджрд╕ рддрдХ рд╕реАрдорд┐рдд рдХрд░ рджреЗрдВрдЧреЗред


рдЬрдм рдореЗрд░реЗ рдЕрднреНрдпрд╛рд╕ рдореЗрдВ рдПрдХ рд╕рдорд╛рди рдХрд╛рд░реНрдп рдХрд╛ рд╕рд╛рдордирд╛ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдореИрдВ рддреБрд░рдВрдд рд░реЛрдЬрд▓рд┐рди рдХреА рджрд┐рд╢рд╛ рдореЗрдВ рджреЗрдЦрддрд╛ рд╣реВрдВ, рдореБрдЭреЗ рдПрдХ рд╣реА рддрд░рд╣ рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд▓рд┐рдЦрдиреЗ рдФрд░ рдХреЙрдкреА рдкреЗрд╕реНрдЯ рдХрд░рдиреЗ рдХрд╛ рдорди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЙрдиреНрд╣реЗрдВ рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИред


рдЗрд╕рдореЗрдВ рдЬреЗрдиреЗрд░рд┐рдХ рд╣рдорд╛рд░реА рдорджрдж рдХрд░реЗрдВрдЧреЗред рдЬреЗрдирд░рд┐рдХ рдФрд░ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдПрдХ рдЕрд▓рдЧ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде 10 рд╡рд┐рдзрд┐рдпрд╛рдВ рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ


рдкреНрд░рдХреНрд╖реЗрдкреНрдп рдХреЗ рд▓рд┐рдП рдкрд╣рд▓рд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рдерд╛, рдореИрдВ рд▓реИрдореНрдмреНрдбрд╛ рдХреЗ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ (рдЗрдВрдЯ, рд╕реНрдЯреНрд░рд┐рдВрдЧ, рдмреВрд▓рд┐рдпрди, рдбреЗрдЯрд╛рдЗрдо) рдХреЛ рд╕реАрдорд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдФрд░ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред


рдХрдард┐рдирд╛рдИ рдпрд╣ рд╣реИ рдХрд┐ 3 рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рднреА рд╣рдореЗрдВ 64 рдЕрд▓рдЧ-рдЕрд▓рдЧ рдУрд╡рд░рд▓реЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рд╣реЛрдВрдЧреЗ, рдФрд░ рдХреЗрд╡рд▓ рд╕рд╛рдорд╛рдиреНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп 1:


 IMappingExpression<TSource, TDest> To<TSource, TDest, TProjection,T,T1, T2, T3>( this MapperExpressionWrapper<TSource,TDest,TProjection> mapperExpressionWrapper, (Expression<Func<TDest, T>>, Expression<Func<TProjection, T>>) arg0, (Expression<Func<TDest, T1>>, Expression<Func<TProjection, T1>>) arg1, (Expression<Func<TDest, T2>>, Expression<Func<TProjection, T2>>) arg2, (Expression<Func<TDest, T3>>, Expression<Func<TProjection, T3>>) arg3) { ... } 

рд▓реЗрдХрд┐рди рдпрд╣ рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ, рд╣рдо рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рдореЗрдВ рдХреБрдЫ рд╕рдордп рд▓рдЧреЗрдЧрд╛ рдФрд░ рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рддрд░реАрдХреЛрдВ рдХрд╛ рдкреВрд░рд╛ рд╕реЗрдЯ рдорд┐рд▓реЗрдЧрд╛ред


рд╕рдорд╕реНрдпрд╛ рдЕрд▓рдЧ рд╣реИ, ReSharper рдЗрддрдиреЗ рд╕рд╛рд░реЗ рдЕрдзрд┐рднрд╛рд░ рдирд╣реАрдВ рдЙрдард╛рдПрдВрдЧреЗ рдФрд░ рдмрд╕ рдХрд╛рдо рдХрд░рдиреЗ рд╕реЗ рдЗрдирдХрд╛рд░ рдХрд░ рджреЗрдВрдЧреЗ, рдЖрдк Intellisience рдЦреЛ рджреЗрдВрдЧреЗ рдФрд░ IDE рд▓реЛрдб рдХрд░реЗрдВрдЧреЗред


рд╣рдо рдПрдХ рдРрд╕реА рд╡рд┐рдзрд┐ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдПрдХ рдЯрдкрд▓ рд▓реЗрддреА рд╣реИ:


 public static IMappingExpression<TSource, TDest> To <TSource, TDest, TProjection, T>(this MapperExpressionWrapper<TSource,TDest,TProjection> mapperExpressionWrapper, (Expression<Func<TDest, T>>, Expression<Func<TProjection, T>>) arg0) { //    RegisterByConvention(mapperExpressionWrapper); //    expreession RegisterRule(mapperExpressionWrapper, arg0); //  IMappingExpression,     //   extension  return mapperExpressionWrapper.MappingExpression; } 

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдХрдиреНрд╡реЗрдВрд╢рди рджреНрд╡рд╛рд░рд╛ рдХрд┐рд╕ рдкреНрд░реЙрдкрд░реНрдЯреА рдореИрдкрд┐рдВрдЧ рдХреЛ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рдПрдХ рдХрд╛рдлреА рд╕рд░рд▓ рд╡рд┐рдзрд┐ рд╣реИ, рдбреАрдЯреАрдУ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░реЙрдкрд░реНрдЯреА рдХреЗ рд▓рд┐рдП рд╣рдо рдУрд░рд┐рдЬрд┐рдирд▓ рдПрдВрдЯрд┐рдЯреА рдореЗрдВ рд░рд╛рд╕реНрддрд╛ рдЦреЛрдЬрддреЗ рд╣реИрдВред рддрд░реАрдХреЛрдВ рдХреЛ рд░рд┐рдлреНрд▓реЗрдХреНрд╕рд┐рдмрд▓ рдХрд╣рд╛ рдЬрд╛рдирд╛ рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЛ рдПрдХ рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП рд▓реИрдореНрдмреНрдбрд╛ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХрд╛ рдкреНрд░рдХрд╛рд░ рдкреНрд░реЛрдк рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред


рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓реИрдВрдмрдбрд╛ рдХреЛ рджрд░реНрдЬ рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рд╣реИ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ <рдлрдВрдХ <TSource, object >>, рдлрд┐рд░ AutoMapper рдСрдмреНрдЬреЗрдХреНрдЯ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА DTO рдЧреБрдгреЛрдВ рдХреЛ рдореИрдк рдХрд░реЗрдЧрд╛


 private static void RegisterByConvention<TSource, TDest, TProjection>( MapperExpressionWrapper<TSource, TDest, TProjection> mapperExpressionWrapper) { var properties = typeof(TDest).GetProperties().ToList(); properties.ForEach(prop => { // mapperExpressionWrapper.FromExpression = x=>x.Identity.Passport // prop.Name = Name // ruleByConvention Expression<Func<Pupil,string>> x=>x.Identity.Passport.Name var ruleByConvention = _cachedMethodInfo .GetMethod(nameof(HelpersMethod.GetRuleByConvention)) .MakeGenericMethod(typeof(TSource), typeof(TProjection), prop.PropertyType) .Invoke(null, new object[] {prop, mapperExpressionWrapper.FromExpression}); if (ruleByConvention == null) return; // mapperExpressionWrapper.MappingExpression.ForMember(prop.Name, s => s.MapFrom((dynamic) ruleByConvention)); }); } 

рд░рдЬрд┐рд╕реНрдЯрд░рд░реБрд▓реЗ рдПрдХ рдЯрдкрд▓ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдорд╛рдирдЪрд┐рддреНрд░рдг рдирд┐рдпрдореЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЗрд╕реЗ рдЗрд╕рдореЗрдВ "рдХрдиреЗрдХреНрдЯ" рд╣реЛрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ
FromExpression рдФрд░ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ tuple рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░ рджрд┐рдпрд╛ред


рдпрд╣ рд╣рдореЗрдВ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред рдЗрдВрд╡реЛрдХ, рдИрдПрдл рдХреЛрд░ 2.0 рдиреЗ рдЗрд╕рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд┐рдпрд╛, рдмрд╛рдж рдореЗрдВ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдиреЗ рд╕рдорд░реНрдерди рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ред рдпрд╣ рдЖрдкрдХреЛ "рд▓реИрдореНрдмреНрдб рд░рдЪрдирд╛" рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛:


 Expression<Func<Pupil,StudyGroup>> from = x=>x.EducationCard.StudyGroup; Expression<Func<StudyGroup,int>> @for = x=>x.Number; //invoke = x=>x.EducationCard.StudyGroup.Number; var composition = Expression.Lambda<Func<Pupil, string>>( Expression.Invoke(@for,from.Body),from.Parameters.First()) 

рд░рдЬрд┐рд╕реНрдЯрд░ рд╡рд┐рдзрд┐:


 private static void RegisterRule<TSource, TDest, TProjection, T (MapperExpressionWrapper<TSource,TDest,TProjection> mapperExpressionWrapper, (Expression<Func<TDest, T>>, Expression<Func<TProjection, T>>) rule) { //rule = (x=>x.Group,x=>x.Number) var (from, @for) = rule; //      @for = (Expression<Func<TProjection, T>>) _interpolationReplacer.Visit(@for); //mapperExpressionWrapper.FromExpression = (x=>x.EducationCard.StudyGroup) var result = Expression.Lambda<Func<TSource, T>>( Expression.Invoke(@for, mapperExpressionWrapper.FromExpression.Body), mapperExpressionWrapper.FromExpression.Parameters.First()); var destPropertyName = from.PropertiesStr().First(); // result = x => Invoke(x => x.Number, x.EducationCard.StudyGroup) //  ,  result = x=>x.EducationCard.StudyCard.Number mapperExpressionWrapper.MappingExpression .ForMember(destPropertyName, s => s.MapFrom(result)); } 

рдЯрдкрд▓ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╕рдордп рд╡рд┐рдзрд┐ рдХреЛ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд░рдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ рдПрдХ рдФрд░ рдЯрдкрд▓ рдЬреЛрдбрд╝рддреЗ рд╕рдордп, рдЖрдкрдХреЛ рдПрдХ рдФрд░ рдЬреЗрдиреЗрд░рд┐рдХ, рдкреИрд░рд╛рдореАрдЯрд░ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛, рдФрд░ рдирдП рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП RegisterRule рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред


рджреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг:


 IMappingExpression<TSource, TDest> To<TSource, TDest, TProjection, T, T1> (this MapperExpressionWrapper<TSource,TDest,TProjection>mapperExpressionWrapper, (Expression<Func<TDest, T>>, Expression<Func<TProjection, T>>) arg0, (Expression<Func<TDest, T1>>, Expression<Func<TProjection, T1>>) arg1) { RegisterByConvention(mapperExpressionWrapper); RegisterRule(mapperExpressionWrapper, arg0); RegisterRule(mapperExpressionWrapper, arg1); return mapperExpressionWrapper.MappingExpression; } 

рд╣рдо CSharpSyntaxRewriter рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ , рдпрд╣ рдПрдХ рдЖрдЧрдВрддреБрдХ рд╣реИ рдЬреЛ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдХреЗ рдиреЛрдбреНрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рддрд╛ рд╣реИред рд╣рдо рдПрдХ рддрд░реНрдХ рдХреЗ рд╕рд╛рде To рдХреЛ рдЖрдзрд╛рд░ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рдЬреЗрдиреЗрд░рд┐рдХ рдкреИрд░рд╛рдореАрдЯрд░ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдФрд░ RegisterRule рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ;


 public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node) { //     To if (node.Identifier.Value.ToString() != "To") return base.VisitMethodDeclaration(node); // returnStatement = return mapperExpressionWrapper.MappingExpression; var returnStatement = node.Body.Statements.Last(); //beforeReturnStatements: //[RegisterByConvention(mapperExpressionWrapper), // RegisterRule(mapperExpressionWrapper, arg0)] var beforeReturnStatements = node.Body.Statements.SkipLast(1); //   RegisterRule  returStatement var newBody = SyntaxFactory.Block( beforeReturnStatements.Concat(ReWriteMethodInfo.Block.Statements) .Concat(new[] {returnStatement})); //     return node.Update( node.AttributeLists, node.Modifiers, node.ReturnType, node.ExplicitInterfaceSpecifier, node.Identifier, node.TypeParameterList.AddParameters (ReWriteMethodInfo.Generics.Parameters.ToArray()), node.ParameterList.AddParameters (ReWriteMethodInfo.AddedParameters.Parameters.ToArray()), node.ConstraintClauses, newBody, node.SemicolonToken); } 

ReWriteMethodInfo рдореЗрдВ рдЙрддреНрдкрдиреНрди рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЯреНрд░реА рдиреЛрдбреНрд╕ рд╣реЛрддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдкрдХреЛ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред рдЙрд╕рдХреЗ рдмрд╛рдж, рд╣рдореЗрдВ MethodDeclarationSyntax (рдПрдХ рд╡рд┐рдзрд┐ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЯреНрд░реА) рдкреНрд░рдХрд╛рд░ рдХреА 10 рд╡рд╕реНрддреБрдУрдВ рдХреА рд╕реВрдЪреА рдорд┐рд▓рддреА рд╣реИред


рдЕрдЧрд▓реЗ рдЪрд░рдг рдореЗрдВ, рд╣рдо рдЙрд╕ рдХреНрд▓рд╛рд╕ рдХреЛ рд▓реЗрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдореЗрдердб рдирд┐рд╣рд┐рдд рд╣реИ рдФрд░ рдЕрдиреНрдп рд╡рд┐рдЬрд╝рд┐рдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕рдореЗрдВ рд╕рднреА рдирдП рддрд░реАрдХреЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рд╣рдо VisitClassDeclatation рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред


рдЕрджреНрдпрддрди рд╡рд┐рдзрд┐ рдЖрдкрдХреЛ рдореМрдЬреВрджрд╛ рдЯреНрд░реА рдиреЛрдб рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИ, рд╣реБрдб рдХреЗ рддрд╣рдд рд╕рднреА рддрд░реНрдХреЛрдВ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдХрдо рд╕реЗ рдХрдо рдПрдХ рдореВрд▓ рд╕реЗ рдЕрд▓рдЧ рд╣реИ, рддреЛ рдПрдХ рдирдпрд╛ рдиреЛрдб рдмрдирд╛рддрд╛ рд╣реИред


 public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node) { //todo refactoring it return node.Update( node.AttributeLists, node.Modifiers, node.Keyword, node.Identifier, node.TypeParameterList, node.BaseList, node.ConstraintClauses, node.OpenBraceToken, new SyntaxList<MemberDeclarationSyntax>(ReWriteMethods), node.CloseBraceToken, node.SemicolonToken); } 

рдЕрдВрдд рдореЗрдВ, рд╣рдореЗрдВ рдПрдХ SyntaxNode рдорд┐рд▓рддрд╛ рд╣реИ - рдПрдХ рдХреНрд▓рд╛рд╕ рдЬрд┐рд╕рдореЗрдВ рдЬреЛрдбрд╝реЗ рдЧрдП рддрд░реАрдХреЗ рд╣реИрдВ, рдиреЛрдб рдХреЛ рдПрдХ рдирдИ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд▓рд┐рдЦреЗрдВред рдЕрдм рд╣рдордиреЗ 1 рд╕реЗ 10 рдЯреНрдпреВрдкрд▓ рдФрд░ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдорд╛рдирдЪрд┐рддреНрд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Too рд╡рд┐рдзрд┐ рдХреЛ рдУрд╡рд░рд▓реЛрдб рдХрд░ рджрд┐рдпрд╛ рд╣реИред


рд╡рд┐рд╕реНрддрд╛рд░ рдмрд┐рдВрджреБ


рдЖрдЗрдП AutoMapper рдХреЛ рдХреБрдЫ рдФрд░ рдХреЗ рд░реВрдк рдореЗрдВ рджреЗрдЦреЗрдВред рдХреНрд╡реЗрд░реА рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдкреНрд░рджрд╛рддрд╛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рдкрд╛рд░реНрд╕ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдЗрди рдкреНрд░рд╢реНрдиреЛрдВ рдХрд╛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рднрд╛рдЧ рдЕрд▓рдЧ рд╕реЗ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдВ AutoMapper рдЦреЗрд▓ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рд╡рд┐рд╕реНрддрд╛рд░ рдПрдХ рд╡рд┐рд╕реНрддрд╛рд░ рдмрд┐рдВрджреБ рд╣реИ рдЬрд╣рд╛рдВ рд╣рдо рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдирд┐рдпрдореЛрдВ рдХреЛ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред


рд╣рдо рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рд╕реЗ рд╡рд┐рдЬрд╝рд┐рдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ рдЬреЛ рдХрд┐ рд░реЗрдЧрд╕реНрдЯрд░ рд╡рд┐рдзрд┐ рдореЗрдВ рд╕рдВрдЧрддрд┐ рдХреЗ рд╕рд╛рде рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреНрд░рдХреНрд╖реЗрдк рдХреА рдЬрдЧрд╣ рд▓реЗрддрд╛ рд╣реИред рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╕рднреА рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдЬреЛ рдЗрдХрд╛рдИ рд╕реЗ рдорд╛рдирдЪрд┐рддреНрд░рдг рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕ рдЖрдЧрдВрддреБрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рдПрдВрдЧреЗ, рдЬрд┐рд╕рд╕реЗ рд╣рд░ рдмрд╛рд░ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рдПрдЧреА ред рдпрд╣ рдПрдХ рд░рд╛рдордмрд╛рдг рдирд╣реАрдВ рд╣реИ, рдПрдХрдорд╛рддреНрд░ рддрд░реАрдХрд╛ рд╣реИ рдХрд┐ рд╣рдо рдХреНрдпрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкреНрд░рдмрдВрдзрди рдПрдХ рдкреНрд░рдХреНрд╖реЗрдкрдг рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрднреА рднреА рдЬреАрд╡рди рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИред


рд╣рдо рдХреБрдЫ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ extention'y рднреА рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╢рд░реНрдд рджреНрд╡рд╛рд░рд╛ рдорд╛рдирдЪрд┐рддреНрд░рдг рдХреЗ рд▓рд┐рдП:


 CreateMap<Passport,PassportDto>() .ToIf(x => x.Age, x => x < 18, x => $"{x.Age}", x => "Adult") 

рдореБрдЦреНрдп рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕рдХреЗ рд╕рд╛рде рдЦреЗрд▓рдирд╛ рдирд╣реАрдВ рд╣реИ рдФрд░ рдкреНрд░рджрд░реНрд╢рди рд╕реНрддрд░ рдкрд░ рдЬрдЯрд┐рд▓ рддрд░реНрдХ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдирд╣реАрдВ рдХрд░рдирд╛ рд╣реИ
Github

Source: https://habr.com/ru/post/hi444934/


All Articles