Automapper : Entity Framework 4를 사용하여 컬렉션의 상속 및 추상 기본 클래스와 매핑 문제 프록시 Pocos

.net automapper collections entity-framework poco

문제

AutoMapper (뛰어난 기술)를 사용하여 비즈니스 개체를 DTO에 매핑하는 데 문제가 있습니다. DTO는 컬렉션 내의 추상 기본 클래스를 상속 한 것입니다.

여기 내 물건들이있다.

abstract class Payment
class CashPayment : Payment
class CreditCardPayment : Payment

나는 또한 다음과 같은 지불금 컬렉션을 포함하는 Invoice 오브젝트를 가지고있다.

    public class Invoice
    {
       ... properties...

       public ICollection<Payment> Payments { get; set; }
    }

또한 각각의 객체에 해당하는 DTO 버전이 있습니다.

DtoInvoice 객체는 다음과 같이 정의됩니다.

[DataContract]
public class DtoInvoice
{
   ...properties...

   [DataMember]
   public List<DtoPayment> Payments { get; set; }
}

이것이 내 Mapper 정의의 모습입니다.

Mapper.CreateMap<Invoice, DtoInvoice>();

Mapper.CreateMap<Payment, DtoPayment>()
  .Include<CashPayment, DtoCashPayment>()
  .Include<CreditCardPayment, DtoCreditCardPayment>();

Mapper.CreateMap<CashPayment, DtoCashPayment>();
Mapper.CreateMap<CreditCardPayment, DtoCreditCardPayment>();

매핑을 수행하는 코드는 다음과 같습니다.

var invoice = repo.GetInvoice(invoiceId);

var dtoInvoice = Mapper.Map<Invoice, DtoInvoice>(invoice);

예를 들어 매퍼가 매핑하려고 시도 할 때 인보이스 오브젝트에 특정 지불금 모음 (예 : 1 현금 및 1 신용 카드)이 포함 된 경우 추상 클래스 지불을 생성 할 수 없다는 오류가 발생합니다. 지불 오브젝트에서 추상 키워드를 제거하면 코드는 작동하지만 지불 오브젝트 콜렉션 만 얻고 특정 오브젝트 (현금 및 신용 카드 지불)를 얻지 못합니다.

따라서 질문은 : 어떻게 AutoMapper가 기본 클래스가 아닌 특정 지불 유형을 매핑 할 수 있습니까?


최신 정보

나는 좀 더 파고를했고 문제가 있다고 생각하지만 AutoMapper로 어떻게 해결할 수 있을지 모르겠다. 나는 이것이 EF의 문제라고 생각하고 AutoMapper의 잘못이 아니라고 생각한다. :-)

내 코드에서는 Entity Framework 4 프록시 POCO를 지연로드와 함께 사용하고 있습니다.

그래서 프록시 POCO 인 EF에서 반환 된 엔티티를 매핑하려고하면 다음과 같은 재미있는 유형을 얻습니다.

System.Data.Entity.DynamicProxies.CashPayment_86783D165755C316A2F58A4343EEC4842907C5539AF24F0E64AEF498B15105C2

그래서 내 이론은 AutoMapper가 CashPayment를 DtoCashPayment에 매핑하려고 할 때 전달되는 지불이 프록시 유형이라고 가정 할 때 AutoMapper는이를 "일치하지 않음"으로보고 일반 지불 유형을 매핑합니다. 그러나 Payment가 "System.InvalidOperationException : 추상 클래스의 인스턴스를 만들 수없는"추상 클래스 AutoMapper 폭탄이기 때문에. " 예외.

그래서 질문입니다 : AutoMapper를 사용하여 EF POCO 프록시 개체를 Dtos에 매핑하는 방법이 있습니까?

수락 된 답변

이 답변은 EF4 POCO 프록시에 대해 동일한 문제에 직면했기 때문에 '조금 늦었습니다.'

필자는 Mapper.DynamicMap<TDestination>(object source) 을 호출하여 .Include<TOtherSource, TOtherDestinatio>() 대신 런타임 형식 변환을 호출하는 사용자 지정 변환기를 사용 Mapper.DynamicMap<TDestination>(object source) 문제를 해결했습니다.

그것은 나를 위해 잘 작동합니다.

귀하의 경우 다음과 같은 변환기를 정의 할 것입니다 :

class PaymentConverter : ITypeConverter<Payment, DtoPayment> {
    public DtoPayment Convert( ResolutionContext context ) {
        return Mapper.DynamicMap<DtoPayment>( context.SourceValue );
    }
}

그리고:

Mapper.CreateMap<Payment, DtoPayment>().ConvertUsing<PaymentConverter>();
Mapper.CreateMap<CashPayment, DtoCashPayment>();
Mapper.CreateMap<CreditCardPayment, DtoCreditCardPayment>();

인기 답변

또한 Olivier의 예제를 시도하고 동일한 StackOverflow 오류가 발생했습니다. 나는 또한 subkamran의 솔루션을 시도했지만 엔티티 모델 코드 생성에서 기본 클래스를 사용하지 않기 때문에 운이 좋지 않습니다. 오토매 퍼는 여전히 폭발적이다. 더 나은 솔루션을 찾을 때까지 Context 객체를 만들 때 Context가 프록시를 만들지 않도록 설정했습니다.

model.Configuration.ProxyCreationEnabled = false; 
model.Configuration.LazyLoadingEnabled = true; 

Automapper에 무언가를 사용하여 문제에 대한 해답을보고 싶습니다.

업데이트 : Automapper의 사전 릴리스는이 문제를 해결하고 추가 구성없이 DynamicProxy를 포함하도록 매핑을 허용합니다.

이 작품은 2.2.1 릴리스입니다



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.