'Autmapper map collections of different types to collection of another type with nesting
I am currently struggling with automapper.10.1.1 config. I have following types:
class Response
{
List<Assignment> Assignments { get; }
List<Product> Products { get; }
}
class Assignment
{
int AssignmentId { get; set; }
int ProductId { get; set; } // references Product.ProductId
}
class Product
{
int ProductId { get; set; }
}
class AssignmentModel
{
int AssignmentId { get; set; }
int ProductId { get; set; }
Product Product { get; set; }
}
For every item in the "Assignments" property of the response object, I would like to get a new AssignmentModel with the corresponding product based on the product id.
The current solution works by mapping the Assignments into new AssignmentModels and the Products into the existing AssignmentModels. The downside is, that I have to call the mapper twice.
cfg.CreateMap<Assignment, AssignmentModel>();
cfg.CreateMap<Product, AssignmentModel>()
.ForMember(
d => d.Product, opt => opt.MapFrom(s => s))
.EqualityComparison((s, d) => s.ProductId == d.ProductId)
.ForAllOtherMembers(opt => opt.Ignore());
var assignments = mapper.Map<ICollection<AssignmentModel>>(response.Assignments);
mapper.Map(response.Products, assignments); // not using the result because it does not return assignments without products
return assignments;
Is it possible to do that in one call? like so:
return mapper.Map<ICollection<AssignmentModel>>(response);
Solution 1:[1]
Would suggest using Custom Type Resolver for your scenario.
Mapping Configuration / Profile
cfg.CreateMap<Assignment, AssignmentModel>();
cfg.CreateMap<Response, ICollection<AssignmentModel>>()
.ConvertUsing<ResponseAssignmentModelCollectionConverter>();
In the Custom Type Converter:
source.Assignments
Map toList<AssignmentModel>
.- Use LINQ
.Join()
to join the result from 1 andsource.Products
byProductId
.
public class ResponseAssignmentModelCollectionConverter : ITypeConverter<Response, ICollection<AssignmentModel>>
{
public ICollection<AssignmentModel> Convert(Response source, ICollection<AssignmentModel> destination, ResolutionContext context)
{
var _mapper = context.Mapper;
var result = _mapper.Map<List<AssignmentModel>>(source.Assignments);
result = result.Join(source.Products,
a => a.ProductId,
b => b.ProductId,
(a, b) =>
{
a.Product = b;
return a;
})
.ToList();
return result;
}
}
mapper.Map<ICollection<AssignmentModel>>(response);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |