I know the basics of Automapper but I was wondering if it can also do more complex things or if I am forced to do things like that manually. Let me explain it with my current scenario.
OrderStatusDTO
public class OrderStatusDTO
{
[Required]
public int[] OrderIds { get; set; }
[Required]
public int StatusId { get; set; }
[MaxLength(50)]
public string Username { get; set; }
public string Comment { get; set; }
[Required]
public DateTime Date { get; set; }
}
The purpose of this DTO is fairly simple; it creates an order status for multiple orders at the same time.
OrderStatus
public class OrderStatus
{
[Required]
public int Id { get; set; }
[Required]
public int OrderId { get; set; }
[Required]
public int StatusId { get; set; }
[MaxLength(50)]
public string Username { get; set; }
public string Comment { get; set; }
[Required]
public DateTime Date { get; set; }
}
This is the database entity. StatusId
, Username
, Comment
and Date
will be the same for all of them and there should be as many OrderStatus objects as the size of the OrderStatusDTO.OrderIds
array. Each object's OrderId
property will match with one of the values of the OrderStatusDTO.OrderIds
array.
Is it possible to use Automapper for this, such that I could to something like this as the final result:
_mapper.Map<OrderStatusDTO, List<OrderStatus>>(orderStatusDTO);
Edit :
In a loop, it would look like the following.
List<OrderStatus> orderStatus = new List<OrderStatus>();
for (int i = 0; i < orderStatusDTO.OrderIds.Length; i++) {
OrderStatus orderStatus = new OrderStatus();
orderStatus.OrderId = orderStatusDTO.OrderIds[i];
orderStatus.StatusId = orderStatusDTO.StatusId;
orderStatus.Username = orderStatusDTO.Username;
orderStatus.Comment = orderStatusDTO.Comment;
orderStatus.Date = orderStatusDTO.Date;
orderStatus.Add(orderStatus);
}
Use ProjectTo method for collections.
List<OrderStatus> orderStatus = orderStatusDTO
.AsQueryable()
.ProjectTo<OrderStatus>()
.ToList();
Source:automapper.org
You have to provide automapper
configuration like this -
cfg.CreateMap<OrderStatusDTO, List<OrderStatus>>()
.ConvertUsing<OrderStatusDTOConverter>();
Where, OrderStatusDTOConverter
is defined as -
public class OrderStatusDTOConverter : ITypeConverter<OrderStatusDTO, List<OrderStatus>>
{
public List<OrderStatus> Convert(OrderStatusDTO source, List<OrderStatus> destination, ResolutionContext context)
{
var list = new List<OrderStatus>();
foreach (var orderId in source.OrderIds)
{
list.Add(new OrderStatus
{
Comment = source.Comment,
Date = source.Date,
OrderId = orderId,
StatusId = source.StatusId,
Username = source.Username
});
}
return list;
}
}
Now Map
as -
var orderList = mapper.Map<List<OrderStatus>>(orderDTO);
And if you want reverse as well, Add configuration as -
cfg.CreateMap<List<OrderStatus>, OrderStatusDTO>()
.ForMember(p => p.OrderIds, opts => opts.MapFrom(s => s.Select(r => r.OrderId).ToArray()))
.ForMember(p => p.StatusId, opts => opts.MapFrom(s => s.Any() ? s.FirstOrDefault().StatusId : 0))
.ForMember(p => p.Username, opts => opts.MapFrom(s => s.Any() ? s.FirstOrDefault().Username : string.Empty))
.ForMember(p => p.Date, opts => opts.MapFrom(s => s.Any() ? s.FirstOrDefault().Date : new DateTime()))
.ForMember(p => p.Comment, opts => opts.MapFrom(s => s.Any() ? s.FirstOrDefault().Username : string.Empty));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.