Automapper:使用 Entity Framework 4 Proxy Pocos 的集合上的继承和抽象基类的映射问题 [英] Automapper : mapping issue with inheritance and abstract base class on collections with Entity Framework 4 Proxy Pocos

查看:29
本文介绍了Automapper:使用 Entity Framework 4 Proxy Pocos 的集合上的继承和抽象基类的映射问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 AutoMapper(这是一项出色的技术)将业务对象映射到 DTO 时遇到问题,我在该 DTO 中从集合中的抽象基类继承.

I am having an issue using AutoMapper (which is an excellent technology) to map a business object to a DTO where I have inheritance off of an abstract base class within a collection.

这是我的对象:

abstract class Payment
class CashPayment : Payment
class CreditCardPayment : Payment

我还有一个发票对象,其中包含一组付款,如下所示:

I also have an invoice object which contains a collection of payments like so:

    public class Invoice
    {
       ... properties...

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

对于这些对象,我也有相应的 DTO 版本.

I also have corresponding DTO versions of each of these objects.

DtoInvoice 对象定义为:

The DtoInvoice object is defined as:

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

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

这是我的 Mapper 定义的样子:

This is what my Mapper definitions look like:

Mapper.CreateMap<Invoice, DtoInvoice>();

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

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

执行映射的代码如下所示:

The code to perform the mapping looks like this:

var invoice = repo.GetInvoice(invoiceId);

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

例如,如果我的发票对象包含一组特定的付款(比如 1 个现金和 1 张信用卡),当映射器尝试映射它们时,我会收到一个错误,提示无法创建抽象类 Payment.如果我从 Payment 对象中删除 abstract 关键字,那么代码可以工作,但我只得到 Payment 对象的集合,我没有得到它们的特定对象(现金和信用卡付款).

So for example if my invoice object contains a collection of specific payments (say 1 cash and 1 credit card) when mapper tries to map them I get an error that the abstract class Payment cannot be created. If I remove the abstract keyword from the Payment object then the code works but I only get a collection of Payment object, I do not get their specific objects (Cash & Credit Card payments).

所以问题是:如何让 AutoMapper 映射特定的支付类型而不是基类?

So the question is: How can I get AutoMapper to map the specific payment types and not the base class?

更新

我进行了更多挖掘,并认为我发现了问题,但不确定如何使用 AutoMapper 解决此问题.我认为这更像是 EF 的事情,而不是 AutoMapper 的错.:-)

I did some more digging and think I see a problem but am not sure how I can solve this with AutoMapper. I think this is more of an EF thing and not AutoMapper's fault. :-)

在我的代码中,我使用带有延迟加载的 Entity Framework 4 代理 POCO.

In my code I am using Entity Framework 4 Proxy POCOs with lazy loading.

因此,当我尝试映射从代理 POCO 的 EF 返回的实体时,它会得到看起来很有趣的类型,例如:

So when I try to map an entity returned from EF that is a proxy POCO it gets that funny looking type like:

System.Data.Entity.DynamicProxies.CashPayment_86783D165755C316A2F58A4343EEC4842907C5539AF24F0E64AEF498B15105C2

所以我的理论是,当 AutoMapper 尝试将 CashPayment 映射到 DtoCashPayment 并且传入的付款是代理类型时,AutoMapper 将其视为不匹配",然后映射通用付款类型.但是由于 Payment 是一个抽象类,AutoMapper 会用System.InvalidOperationException:无法创建抽象类的实例"来轰炸.例外.

So my theory is that when AutoMapper tries to map CashPayment to DtoCashPayment and the payment passed in is of the proxy type AutoMapper sees it as a "non match" and then maps the generic Payment type. But since Payment is an abstract class AutoMapper bombs with a "System.InvalidOperationException: Instances of abstract classes cannot be created." exception.

所以问题是:有没有办法让我使用 AutoMapper 将 EF POCO 代理对象映射到 Dtos.

So the question is: Is there a way for me to use AutoMapper to map EF POCO proxy objects to Dtos.

推荐答案

这个答案来得有点晚,因为我刚刚在 EF4 POCO 代理上遇到了同样的问题.

This answer comes 'a bit' late as I've just faced the same issue with EF4 POCO proxies.

我使用自定义转换器解决了这个问题,该转换器调用 Mapper.DynamicMap(object source) 来调用运行时类型转换,而不是 .Include().

I solved it using a custom converter that calls Mapper.DynamicMap<TDestination>(object source) to invoke the runtime type conversion, rather than the .Include<TOtherSource, TOtherDestinatio>().

它对我来说很好.

在您的情况下,您将定义以下转换器:

In your case you would define the following converter:

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>();

这篇关于Automapper:使用 Entity Framework 4 Proxy Pocos 的集合上的继承和抽象基类的映射问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆