У меня возникла проблема с использованием 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 кредитную карту), когда картограф пытается их сопоставить, я получаю сообщение об ошибке, которую не может быть создан абстрактный класс Payment. Если я удалю ключевое слово abstract из объекта "Оплата", тогда код работает, но я получаю только коллекцию объекта "Платеж", я не получаю их конкретные объекты (оплата наличными и кредитной картой).
Итак, вопрос: как я могу заставить AutoMapper отображать конкретные типы платежей, а не базовый класс?
Обновление
Я сделал еще несколько копаний и думаю, что вижу проблему, но не уверен, как я могу решить эту проблему с помощью AutoMapper. Я думаю, что это скорее вещь EF, а не ошибка AutoMapper.: -)
В моем коде я использую Entity Framework 4 Proxy POCOs с ленивой загрузкой.
Поэтому, когда я пытаюсь отобразить объект, возвращенный из EF, который является прокси-сервером POCO, он получает этот забавный вид типа:
System.Data.Entity.DynamicProxies.CashPayment_86783D165755C316A2F58A4343EEC4842907C5539AF24F0E64AEF498B15105C2
Итак, моя теория заключается в том, что, когда AutoMapper пытается сопоставить CashPayment с DtoCashPayment, а полученный платеж является прокси-типом, AutoMapper видит его как "несоответствие", а затем отображает общий тип платежа. Но так как оплата представляет собой абстрактные классы автомапперных бомб с помощью "System.InvalidOperationException: экземпляры абстрактных классов не могут быть созданы". исключение.
Итак, вопрос: есть ли способ использовать AutoMapper для сопоставления прокси-объектов EF POCO с Dtos.