AutoMapper는 여러 소스에서 변환
두 개의 모델 클래스가 있다고 가정 해 보겠습니다.
public class People {
public string FirstName {get;set;}
public string LastName {get;set;}
}
또한 수업 전화 :
public class Phone {
public string Number {get;set;}
}
그리고 다음과 같이 PeoplePhoneD로 변환하고 싶습니다.
public class PeoplePhoneDto {
public string FirstName {get;set;}
public string LastName {get;set;}
public string PhoneNumber {get;set;}
}
내 컨트롤러에서 내가 가지고 있다고 가정 해 봅시다.
var people = repository.GetPeople(1);
var phone = repository.GetPhone(4);
// normally, without automapper I would made
return new PeoplePhoneDto(people, phone) ;
이 시나리오에 대한 예를 찾을 수없는 것 같습니다. 이것이 가능한가 ?
참고 :이 질문에 대한 예제는 실제가 아닙니다.
여러 소스를 단일 대상에 직접 매핑 할 수 없습니다 . Andrew Whitaker 답변에 설명 된대로지도를 하나씩 적용해야합니다 . 따라서 모든 매핑을 정의해야합니다.
Mapper.CreateMap<People, PeoplePhoneDto>();
Mapper.CreateMap<Phone, PeoplePhoneDto>()
.ForMember(d => d.PhoneNumber, a => a.MapFrom(s => s.Number));
그런 다음 이러한 매핑 중 하나를 사용하여 대상 개체를 만들고 생성 된 개체에 다른 매핑을 적용합니다. 이 단계는 매우 간단한 확장 방법으로 단순화 할 수 있습니다.
public static TDestination Map<TSource, TDestination>(
this TDestination destination, TSource source)
{
return Mapper.Map(source, destination);
}
사용법은 매우 간단합니다.
var dto = Mapper.Map<PeoplePhoneDto>(people)
.Map(phone);
Tuple
이것을 위해 사용할 수 있습니다 .
Mapper.CreateMap<Tuple<People, Phone>, PeoplePhoneDto>()
.ForMember(d => d.FirstName, opt => opt.MapFrom(s => s.Item1.FirstName))
.ForMember(d => d.LastName, opt => opt.MapFrom(s => s.Item1.LastName))
.ForMember(d => d.Number, opt => opt.MapFrom(s => s.Item2.Number ));
더 많은 소스 모델이있는 경우 다른 표현 (목록, 사전 또는 기타)을 사용하여 이러한 모든 모델을 소스로 모을 수 있습니다.
위의 코드는 일부 AutoMapperConfiguration 파일에 배치하고 한 번 전체적으로 설정 한 다음 적용 가능한 경우 사용하는 것이 좋습니다.
AutoMapper는 기본적으로 단일 데이터 소스 만 지원합니다. 예를 들어 두 소스 모델에 동일한 이름의 속성이있는 경우 어떻게 알 수 있기 때문에 여러 소스를 직접 설정할 가능성이 없습니다 (컬렉션으로 묶지 않고).
이를 달성하기위한 몇 가지 해결 방법이 있습니다.
public static class EntityMapper
{
public static T Map<T>(params object[] sources) where T : class
{
if (!sources.Any())
{
return default(T);
}
var initialSource = sources[0];
var mappingResult = Map<T>(initialSource);
// Now map the remaining source objects
if (sources.Count() > 1)
{
Map(mappingResult, sources.Skip(1).ToArray());
}
return mappingResult;
}
private static void Map(object destination, params object[] sources)
{
if (!sources.Any())
{
return;
}
var destinationType = destination.GetType();
foreach (var source in sources)
{
var sourceType = source.GetType();
Mapper.Map(source, destination, sourceType, destinationType);
}
}
private static T Map<T>(object source) where T : class
{
var destinationType = typeof(T);
var sourceType = source.GetType();
var mappingResult = Mapper.Map(source, sourceType, destinationType);
return mappingResult as T;
}
}
그리고:
var peoplePhoneDto = EntityMapper.Map<PeoplePhoneDto>(people, phone);
But to be quite honest, even though I am using AutoMapper for already a few years I have never had a need to use mapping from multiple sources. In cases when for example I needed multiple business models in my single view model I simply embedded these models within the view model class.
So in your case it would look like this:
public class PeoplePhoneDto {
public People People { get; set; }
public Phone Phone { get; set; }
}
If you have a scenario when destination type should be mapped from one of sources and you want to use linq projections, you can do following.
Mapper.CreateMap<People, PeoplePhoneDto>(MemberList.Source);
Mapper.CreateMap<Phone, PeoplePhoneDto>(MemberList.Source)
.ForMember(d => d.PhoneNumber, a => a.MapFrom(s => s.Number));
CreateMap<PeoplePhoneDto,(People,Phone)>(MemberList.Destination)
.ForMember(x => x.Item1, opts => opts.MapFrom(x => x))
.ForMember(x => x.Item2, opts => opts.MapFrom(x => x.PhoneNumber))
.ReverseMap();
I needed this mostly for cross apply queries like this.
var dbQuery =
from p in _context.People
from ph in _context.Phones
.Where(x => ...).Take(1)
select ValueTuple.Create(p, ph);
var list = await dbQuery
.ProjectTo<PeoplePhoneDto>(_mapper.ConfigurationProvider)
.ToListAsync();
참고URL : https://stackoverflow.com/questions/21413273/automapper-convert-from-multiple-sources
'Programing' 카테고리의 다른 글
부모 활동을 동적으로 설정 (0) | 2020.12.12 |
---|---|
SBT에서 Scala 프로젝트에 Java 버전을 적용합니까? (0) | 2020.12.12 |
매개 변수화 된 쿼리는… 제공되지 않은 매개 변수 '@units'를 예상합니다. (0) | 2020.12.12 |
jq 또는 대체 명령 줄 도구를 사용하여 JSON 파일 비교 (0) | 2020.12.12 |
JVM GC가 참조 비교 중에 객체를 이동하여 양쪽이 동일한 객체를 참조하더라도 비교가 실패 할 수 있습니까? (0) | 2020.12.12 |