4

I have a db entity which stores the Order Addresses like this...

enter image description here

And I have the 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 the EF entity to the above classes on the basis of AddressType column. Can anybody explain me how to do that ?

UPDATE

I want to map to OR.DeliveryAddress if the addressType is "Delivery" and to OR.InvoiceAddress if the addressType is "Invoice"

So far, I have been able to do this, but I don't know how to apply condition on 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 the Fiddle that I could come up with for my problem...

6
  • Do you want to map to OR.DeliveryAddress if the addressType is "Delivery" and to OR.InvoiceAddress if the addressType is "Invoice" ? Commented Sep 4, 2014 at 6:00
  • yes, you are right... Commented Sep 4, 2014 at 6:05
  • I don't think you should use subtypes here but just copy the address type. AutoMapper doesn't have tooling for this. Commented Sep 4, 2014 at 7:01
  • @GertArnold What do you mean by not using subtypes ? Commented Sep 4, 2014 at 7:55
  • Ah, they're not sub types. Well, just use one type including an address type property. Commented Sep 4, 2014 at 7:57

2 Answers 2

2

You can create a customer mapper to object. And also you don't have to specify each property using ForMember because if the difference is only upper case / lower case (unless for PersonName), by default AutoMapper is case insensitive when mapping the property name.

Create a custom mapper to 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 mapper.

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

Usage.

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

The actual orderAddressDto type will be based on the addressType. If you have an interface or base class for OR.DeliveryAddress and OR.InvoiceAddress that would be more strongly type. Then replace the object type with the interface / base class.

Sign up to request clarification or add additional context in comments.

9 Comments

I have List<OrderAddress> in the Order entity and when I call AutoMapper.Map<Order>(order);. Will it work?
@NaveedButt, you can just map the property like this var result = AutoMapper.Map<object[]>(order.OrderAddresses);
I used this, but it did not work, so not marking your answer. I am still looking for the answer. I managed to do it using Linq queries, i.e., populate the object manually...
@NaveedButt, Did you map the order address directly? or from the order? How did you map it?
@NaveedButt, in the question there is no usage of map, just configuration, let me clarify again, did you use var orderAddressDto = Mapper.Map<object>(orderAddress) or var orderDto = Mapper.Map<object>(order) or var addressesDto = Mapper.Map<object[]>(order.OrderAddresses) or something else ?
|
0

You may want to try taking a look at ResolveUsing

Semi-pseudo code, as I don't know what your entire Domain Model looks like:

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

I'm assuming here that you have an actual Order entity, which you're trying to make to an 'OrderDto' which only contains one address field.

1 Comment

There is a List<OrderAddress> in the Order entity plus. This is the way to convert the Entity to DTO. What would be the way to convert the DTO back to Entity? I think I would have to use Yuliam's method for that, right ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.