Automapper: проблема с отображением с наследованием и абстрактным базовым классом в коллекциях с Entity Framework 4 Proxy Pocos

У меня возникла проблема с использованием AutoMapper (что является отличной технологией) для сопоставления бизнес-объекта с DTO, где у меня есть наследование от абстрактного базового класса в коллекции.

мои объекты:

abstract class Payment
class CashPayment : Payment
class CreditCardPayment : Payment

У меня также есть объект счета, который содержит коллекцию платежей, например:

    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 кредитная карта) когда mapper пытается отобразить их, я получаю сообщение об ошибке, что абстрактный класс Payment не может быть создан. Если я удаляю абстрактное ключевое слово из объекта Payment, то код работает, но я получаю только коллекцию объектов Payment, я не получаю их конкретные объекты (платежи наличными и кредитной картой).

Поэтому возникает вопрос: как я могу заставить AutoMapper отображать конкретные типы платежей, а не базовый класс?


Обновление

Я провел еще несколько копаний и думаю, что вижу проблему, но не уверен, как решить эту проблему с AutoMapper. Я думаю, что это скорее вещь EF, а не вина AutoMapper. : -)

В моем коде я использую POCO-прокси Entity Framework 4 с отложенной загрузкой.

Поэтому, когда я пытаюсь отобразить сущность, возвращенную из EF, которая является POCO-прокси, она получает такой забавный вид, как:

System.Data.Entity.DynamicProxies.CashPayment_86783D165755C316A2F58A4343EEC4842907C5539AF24F0E64AEF498B15105C2

Итак, моя теория заключается в том, что когда AutoMapper пытается сопоставить CashPayment с DtoCashPayment, а переданный платеж имеет тип прокси, AutoMapper видит его как «не совпадающий», а затем сопоставляет общий тип Payment. Но поскольку Payment является абстрактным классом, бомбы AutoMapper имеют «System.InvalidOperationException: экземпляры абстрактных классов не могут быть созданы». исключение.

Поэтому возникает вопрос: есть ли способ использовать AutoMapper для сопоставления прокси-объектов EF POCO с Dtos.

39
задан Ken Burkhardt 15 August 2010 в 20:35
поделиться