4

我有一个数据库实体,它存储这样的订单地址......

在此处输入图像描述

我有这样的 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 实体映射到上述类。谁能解释我该怎么做?

更新

我想映射到OR.DeliveryAddressaddressType 是否为“Delivery”以及OR.InvoiceAddressaddressType 是否为“Invoice”

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

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 讨论之后,这是我可以为我的问题提出的小提琴......

4

2 回答 2

2

您可以创建一个客户映射器来反对。而且您不必指定每个属性使用ForMember,因为如果差异只是大写/小写(除非 for 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那将是更强的类型。然后用接口/基类替换对象类型。

于 2014-09-04T06:17:15.693 回答
0

您可能想尝试看看ResolveUsing

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

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

我在这里假设您有一个实际的 Order 实体,您试图将其制作为仅包含一个地址字段的“OrderDto”。

于 2014-09-04T07:14:29.060 回答