Reputation: 115
I have these classes:
public class Source
{
public string ID { get; set; }
public int Age Name { get; set; }
public virtual ICollection<SourceChild> SourceChildren { get; set; }
}
public class SourceChild
{
public string Name { get; set; }
public string Language { get; set; }
public string SourceId { get; set; }
public virtual Source Source { get; set; }
}
public class Destination
{
public int Age { get; set; }
public string Name { get; set; }
public string Language { get; set; }
public string Id { get; set; }
}
I was mapping these classes using these mappings:
Mapper.CreateMap<SourceChild, Destination>()
.ForMember(item => item.ID, property => property.MapFrom(item => item.SourceId))
.ForMember(item => item.Age, property => property.MapFrom(item => item.Source.Age));
Automapper maps the other two properties automatically. So everything works fine if I try to map SourceChild
into Destination
type. However now I have another class using source and destination types:
public class SourceUser
{
public string ID { get; set; }
public virtual Source Source { get; set; }
}
public class DestinationUser
{
public string Id { get; set; }
public List<Destination> Destinations { get; set; }
}
To illustrate the situation better here is short description on the classes: I have Source
object and SourceChild
children objects. SourceChild
objects contain information in different languages. When I map Source into Destination
I want to input the Source object and receive output of a collection of destination objects. For each SourceChild
object, Source
object had, there should be one Destination
object.SourceUser
simply refers to Source
with a 1-many relation. DestinationUser
had a many - many retion with Destination
class. In other words each DestinationUser
has a list of all Destinations
in all languages. So having all this in mind let's get back to the code.
I have had some luck in writing the code I need. I have come up with this:
Mapper.CreateMap<SourceUser, DestinationUser>()
.AfterMap((source, destination) => Mapper.Map<Source, List<Destination>>(source.Source));
Mapper.CreateMap<Source, List<Destination>>()
.AfterMap((source, destination) => Mapper.Map<List<SourceChild>, List<Destination>>(source.SourceChildren.ToList(), destination));
This works ALMOST well enough, there is one IF though. I am using queryable extensions to process the mapping. When I retrieve a collection of DestinationUsers
, none of them have the property Destinations
mapped. It appears as null. However, if I do the mapping manually like this:
SourceUser SourceUser = Db.GetSourceUser();
DestinationUser DestUser = Db.GetDestinationUser();
DestUser.Destinations = Mapper.Map<List<Destination>>(SourceUser.Source);
everythign works fine. A list fo DestinationUsers is mapped from the instance of Source.
is it possible to avoid manually calling the latter Mapper.Map()
call? Also bear in mind, that the List Destinations may be changed into any other collection. I just want to have a Destination object for each SourceChild
object Source
had.
Upvotes: 1
Views: 2857
Reputation: 115
Turns out I was only one little step away from the solution I was after. All I needed was extending my mapping of SourceUser
and DestinationUser
classes to look like this:
Mapper.CreateMap<SourceUser, DestinationUser>()
.AfterMap((source, destination) => Mapper.Map<Source, List<Destination>>(source.Source, destination.Destinations));
Hope this helps someone, experiencing similar problems to the one I was facing :)
Upvotes: 4