AutoMapper条件实体映射

时间:2014-09-04 05:27:39

标签: c# entity-framework automapper automapper-3

我有一个db实体,它存储像这样的订单地址......

enter image description here

我有像这样的BLL​​课程......

public class DeliveryAddress
{
    public string Id { get; set; }
    public string PersonyName { get; set; }
    public string CompanyName { get; set; }
    public List<string> AddressLines { get; set; }
    public string Zip { get; set; }
    public string City { get; set; }
    public string CountryCode { get; set; }
}

和另一类这样......

public class InvoiceAddress
{
    public string Id { get; set; }
    public string PersonyName { get; set; }
    public string CompanyName { get; set; }
    public List<string> AddressLines { get; set; }
    public string Zip { get; set; }
    public string City { get; set; }
    public string CountryCode { get; set; }
}

我希望在AddressType列的基础上将EF实体映射到上面的类。谁能解释我怎么做?

更新

如果地址类型是&#34;交付&#34;我想映射到OR.DeliveryAddress如果addressType是&#34; Invoice&#34;

,则OR.InvoiceAddress

到目前为止,我已经能够做到这一点,但我不知道如何在实体映射级别上应用条件......

Mapper.CreateMap<OrderAddress, OR.DeliveryAddress>()
       .ForMember(d => d.City, o => o.MapFrom(s => s.city))
       .ForMember(d => d.CompanyName, o => o.UseValue(string.Empty))
       .ForMember(d => d.CountryCode, o => o.MapFrom(s => s.countryCode))
       .ForMember(d => d.Id, o => o.MapFrom(s => s.id))
       .ForMember(d => d.PersonyName, o => o.MapFrom(s => s.name))
       .ForMember(d => d.Zip, o => o.MapFrom(s => s.zip));

更新2

与@Yuliam Here is the Fiddle讨论后,我可以提出我的问题......

2 个答案:

答案 0 :(得分:2)

您可以创建对象的客户映射器。此外,您不必使用ForMember指定每个属性,因为如果差异仅为大写/小写(除非PersonName),默认情况下AutoMapper不区分大小写映射属性名称时。

创建对象的自定义映射器。

public class AddressConverter : ITypeConverter<OrderAddress, object>
{
    public object Convert(ResolutionContext context)
    {
        var o = context.SourceValue as OrderAddress;
        if (o == null) return null;

        if (o.addressType == "Delivery") return Mapper.Map<OR.DeliveryAddress>(o);
        if (o.addressType == "Invoice") return Mapper.Map<OR.InvoiceAddress>(o);
        return null;
    }
}

然后定义映射器。

Mapper.CreateMap<OrderAddress, OR.DeliveryAddress>()
    .ForMember(d => d.PersonyName, o => o.MapFrom(s => s.name));
Mapper.CreateMap<OrderAddress, OR.InvoiceAddress>()
    .ForMember(d => d.PersonyName, o => o.MapFrom(s => s.name));
Mapper.CreateMap<OrderAddress, object>().ConvertUsing<AddressConverter>();

使用。

var orderAddressDto = Mapper.Map<object>(orderAddress);

实际的orderAddressDto类型将基于addressType。如果您有OR.DeliveryAddressOR.InvoiceAddress的接口或基类,则类型更强。然后用interface / base class替换对象类型。

答案 1 :(得分:0)

您可以尝试查看ResolveUsing

半伪代码,因为我不知道您的整个域模型是什么样的:

Mapper.CreateMap<OrderObject, OrderDto>()
    .ForMember(x => x.Address, opt => opt.ResolveUsing(oo => oo.Type == Invoice ? oo.InvoiceAddress : oo.DeliveryAddress));

我在这里假设你有一个实际的Order实体,你试图对一个只包含一个地址字段的'OrderDto'进行实体化。