相关疑难解决方法(0)

Automapper:使用Entity Framework 4 Proxy Pocos在集合上映射继承和抽象基类的问题

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

这是我的对象:

abstract class Payment
class CashPayment : Payment
class CreditCardPayment : Payment
Run Code Online (Sandbox Code Playgroud)

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

    public class Invoice
    {
       ... properties...

       public ICollection<Payment> Payments { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

我还有每个这些对象的相应DTO版本.

DtoInvoice对象定义为:

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

   [DataMember]
   public List<DtoPayment> Payments { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这就是我的Mapper定义:

Mapper.CreateMap<Invoice, DtoInvoice>();

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

Mapper.CreateMap<CashPayment, DtoCashPayment>();
Mapper.CreateMap<CreditCardPayment, DtoCreditCardPayment>();
Run Code Online (Sandbox Code Playgroud)

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

var invoice = repo.GetInvoice(invoiceId);

var dtoInvoice = Mapper.Map<Invoice, DtoInvoice>(invoice);
Run Code Online (Sandbox Code Playgroud)

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

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


更新

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

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

因此,当我尝试映射从EF返回的实体(代理POCO)时,它会获得如下滑稽的类型:

System.Data.Entity.DynamicProxies.CashPayment_86783D165755C316A2F58A4343EEC4842907C5539AF24F0E64AEF498B15105C2
Run Code Online (Sandbox Code Playgroud)

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

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

.net collections entity-framework poco automapper

39
推荐指数
5
解决办法
2万
查看次数

EntityFramework按ID获取对象?

Generics是否可以在不知道类型的情况下从我的EntityFramework中获取对象?

我正在考虑以下方面的事情:

public T GetObjectByID<T>(int id)
{
   return (from i in myDatabase.T where i.ID == id select i);
}
Run Code Online (Sandbox Code Playgroud)

那可行吗?我可以使用Reflection以某种方式将T.GetType().Name其用于表中吗?

编辑
另一个问题是,并非所有可用的表都使用"ID"作为其唯一的列名.

c# linq asp.net reflection entity-framework

26
推荐指数
4
解决办法
7万
查看次数

使用AutoMapper更新现有域模型设置为NULL

我有下面的viewmodel,它与域模型相同(但包含一些额外的属性).

public class ProductViewModel
{
    public string Name { get; set; }
    public string ShortDescription { get; set; }
    public string FullDescription { get; set; }
    public string AdminComment { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

从上面看,我只在视图页面中使用了一些属性.

当我使用Automapper映射我现有的模型时,我的所有viewmodel字段都被映射到domainmodel字段.

Mapper.Map(productViewModel, product);
Run Code Online (Sandbox Code Playgroud)

由于上面的映射,所有未使用的viewmodel字段(默认情况下未使用的viewmodel字段具有NULL值)都映射到域模型.它用NULL值替换我现有的数据库数据.

有没有办法从映射中排除NULL和默认属性值?

笔记:

  • 我遇到了使用Automapper来更新现有的实体POCO
  • 如果我们对排除的属性使用隐藏字段,则将修复上述问题,因为viewmodel将使用隐藏字段来携带数据.但我不喜欢它!
  • 我尝试了以下不起作用的代码:

    Mapper.CreateMap<ProductViewModel, Product>()
          .ForAllMembers(opt =>
               opt.Condition(srs => (!srs.IsSourceValueNull || IsDefaultValue(srs.SourceValue, srs.SourceType))));
    
    Run Code Online (Sandbox Code Playgroud)

编辑:

尝试Automapper后,使用自定义解析器跳过空值(感谢abatishchev).我已经使用了解析器,但得到错误缺少类型映射配置或不支持的映射

我的代码片段:

...
public System.DateTime CreatedOnUtc { get; set; } …
Run Code Online (Sandbox Code Playgroud)

.net c# entity-framework automapper

2
推荐指数
1
解决办法
1532
查看次数