1

Closed

NestedMappings don't work properly when nested type is Array(or Collection)

description

Nested mappings are not taken into consideration when they are arrays or collections.
See attached modified your unit test.

file attachments

Closed Sep 2, 2011 at 10:47 PM by jbogard
All issues moved to GitHub https://github.com/AutoMapper/AutoMapper/issues

comments

BPierzchlewicz wrote Jul 23, 2009 at 8:27 AM

The problem appears only when source maping type equals destination type.
As you can see in attached test, I used:
var dest = Mapper.Map<OuterSource, OuterSource>(source);

This behavior is due to condition in class EnumerableMapperBase:

if (context.DestinationType.IsAssignableFrom(context.SourceType) && context.SourceValue != null)
{
return context.SourceValue;
}

jbogard wrote Aug 16, 2009 at 12:47 AM

I'm not sure I understand the failing test - you're mapping something to itself, so it just returns the object. Do you have one that highlights the collection issue?

BPierzchlewicz wrote Aug 17, 2009 at 6:34 AM

Yes, I am mapping object with the same source and destination type.
OuterSource.InnerArray is an array, and despite of I ignore some fields (Mapper.CreateMap<InnerSource, InnerDest>().ForMember(a => a.IgnoreValue, act => act.Ignore());)
in result set I get InnerArray with all fields.
Maybe I should write:
Mapper.CreateMap<InnerSource, InnerSource>().ForMember(a => a.IgnoreValue, act => act.Ignore());
?

DomiH wrote Oct 8, 2009 at 10:27 AM

Hi!

We had a similar problem (see attached class diagram). I initialized the Mapper as followed:

//Client -> Proxy
Mapper.CreateMap<IndexDocument, Proxy.IndexDocument>();
Mapper.CreateMap<IndexField, Proxy.IndexField>();
Mapper.CreateMap<TextField, Proxy.TextField>();
Mapper.CreateMap<BinaryField, Proxy.BinaryField>();
Mapping from IndexDocument to Proxy.IndexDocument:
var proxy = Mapper.Map<IndexDocument, Proxy.IndexDocument>(document);

My IndexDocument contains 3 TextFields. Therefore my Proxy-IndexDocument should contain 3 Proxy.TextFields as well – but it doesn’t. Instead 3 Proxy.IndexFields have been created. I think the problem lies in the Map Method of EnumerableMapperBase<TEnumerable>:

//Do not use the Generic Type of the IEnumerable, because it could be a base type or interface.
// Instead use the type of the item when iterating over the enumerable.
//Type sourceElementType = TypeHelper.GetElementType(context.SourceType, sourceValue);
Type destElementType = TypeHelper.GetElementType(context.DestinationType);

In the foreach for enumerableValue I retrieve Source- and Destination-Type as follows:

//Use the concret type of the list item
var sourcType = item.GetType();
//Retrieve destination type from mapper
var destinationType = (from m in mapper.ConfigurationProvider.GetAllTypeMaps()
                             where m.SourceType.Equals(sourcType)
                             select m.DestinationType).FirstOrDefault();
I know that is not optimal to retrieve the mapped destination-type for each source-type. There should be a kind of caching. I did not find a way to retrieve the destination-type by only specifying the source-type. I think that would be nice, too. E.g.:

var destinationType = mapper.ConfigurationProvider.FindDestinationType(Type sourceType)
// or
var sourceType = mapper.ConfigurationProvider.FindSourceType(Type destinationType)

Best regards,
Dominik