Reputation: 2901
I have a db entity which stores the Order Addresses like this...
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...
Upvotes: 4
Views: 2754
Reputation: 892
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.
Upvotes: 0
Reputation: 14640
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.
Upvotes: 2