Reputation: 10193
I am struggling with the Automapper syntax. I have a List of PropertySurveys, each containing 1 Property. I wish to map each item on the collection into a new object which combines the 2 classes.
So my code looks like;
var propertySurveys = new List<PropertyToSurveyOutput >();
foreach (var item in items)
{
Mapper.CreateMap<Property, PropertyToSurveyOutput >();
var property = Mapper.Map<PropertyToSurvey>(item.Property);
Mapper.CreateMap<PropertySurvey, PropertyToSurveyOutput >();
property = Mapper.Map<PropertyToSurvey>(item);
propertySurveys.Add(property);
}
My simplified classes look like;
public class Property
{
public string PropertyName { get; set; }
}
public class PropertySurvey
{
public string PropertySurveyName { get; set; }
public Property Property { get; set;}
}
public class PropertyToSurveyOutput
{
public string PropertyName { get; set; }
public string PropertySurveyName { get; set; }
}
So in the PropertyToSurveyOutput object, after the first mapping PropertyName is set. Then after the second mapping PropertySurveyName is set, but PropertyName is overridden to null. How do I fix this?
Upvotes: 21
Views: 56762
Reputation: 17721
Since v8.1 you can use the IncludeMemebers
method in your configuration to map nested objects using existing mappings.
cfg.CreateMap<Property, PropertyToSurveyOutput>();
cfg.CreateMap<PropertySurvey, PropertyToSurveyOutput>()
.IncludeMembers(src => src.Property);
Upvotes: 5
Reputation: 236228
First of all, Automapper supports mapping of collections. You don't need to map each item in a loop.
Second - you don't need to re-create map each time you need to map single object. Put mappings creation to application start code (or before first usage of mapping).
And last - with Automapper you can create mapping and define how to do custom map for some properties:
Mapper.CreateMap<PropertySurvey, PropertyToSurveyOutput>()
.ForMember(pts => pts.PropertyName, opt => opt.MapFrom(ps => ps.Property.PropertyName));
Usage:
var items = new List<PropertySurvey>
{
new PropertySurvey {
PropertySurveyName = "Foo",
Property = new Property { PropertyName = "X" } },
new PropertySurvey {
PropertySurveyName = "Bar",
Property = new Property { PropertyName = "Y" } }
};
var propertySurveys = Mapper.Map<List<PropertyToSurveyOutput>>(items);
Result:
[
{
"PropertyName": "X",
"PropertySurveyName": "Foo"
},
{
"PropertyName": "Y",
"PropertySurveyName": "Bar"
}
]
UPDATE: If your Property
class has many properties, you can define two default mappings - one from Property
:
Mapper.CreateMap<Property, PropertyToSurveyOutput>();
And one from PropertySurvey
. And use first mapping after you used mapping from PropertySurvey
:
Mapper.CreateMap<PropertySurvey, PropertyToSurveyOutput>()
.AfterMap((ps, pst) => Mapper.Map(ps.Property, pst));
Upvotes: 28
Reputation: 388
First rule of automapper property name should be same then only it will map correctly and assign the value but in your case one property name is only "Property" and second property name is "PropertyName" so make property name same it will work for you
Upvotes: -5