AutoMapper entity mapping

I have a db object that stores order addresses like this ...

enter image description here

And I have BLL classes like this ...

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; }
}

      

and another class like this ...

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; }
}

      

and I want to map an EF object with the above classes based on the AddressType column. Can someone explain to me how to do this?

UPDATE

I want to go to OR.DeliveryAddress

if addressType is "Shipping" and OR.InvoiceAddress

if addressType is "Invoice"

So far I could do it, but I don't know how to apply the condition at the entity mapping level ...

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

      

UPDATE 2

After discussion with @Yuliam Here is a scenario I could come up with for my problem ...

+3


source to share


2 answers


You can create a client object for an object. Also, you don't need to specify every property with ForMember

, because if the difference is only uppercase / lowercase (if only for PersonName

), the default AutoMapper

is case insensitive when matching the property name.

Create a custom mapper for the object.

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;
    }
}

      

Then define the handler.



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

      

Using.

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

      

The actual type orderAddressDto

will be based on addressType

. If you have an interface or base class for OR.DeliveryAddress

and OR.InvoiceAddress

that will be more powerful. Then replace the object type with interface / base class.

+1


source


You can try to look at ResolveUsing

Semi-pseudocode as I don't know what your whole domain model looks like:



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

      

I am assuming you have a real Order object that you are trying to do in "OrderDto" that contains only one address field.

0


source







All Articles