SCFi
SCFi

Reputation: 522

AutoMapper not mapping sub property

I am receiving an issue with automapper v6.0.2 where automapper is trying to shove an ICollection into an int instead of the specified collection.

Error:

    Mapping types:
Member_B3B146AB4F61AEDE3DF3639BDBD65BFA5BCA0FC414F11960DC39DA834F2A8CBD -> ICollection`1
System.Data.Entity.DynamicProxies.Memberr_B3B146AB4F61AEDE3DF3639BDBD65BFA5BCA0FC414F11960DC39DA834F2A8CBD -> System.Collections.Generic.ICollection`1[[MemberService.Dto.DependentDetailDto, MemberService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]

Destination path:
MemberDetailDto.Dependents.Dependents

Source value:
System.Data.Entity.DynamicProxies.MbmRosterSubscriber_B3B146AB4F61AEDE3DF3639BDBD65BFA5BCA0FC414F11960DC39DA834F2A8CBD ---> System.OverflowException: Value was either too large or too small for an Int32.

Member

public Member ()
{
   this.Dependents = new HashSet<Dependent>();
}
public virtual ICollection<Dependent> Dependents { get; set; }

AutoMapper Config

CreateMap<Dependent, DependentDetailDto>();
CreateMap<Member, MemberDetailDto>()
                .ForMember(a => a.Dependents, o => o.MapFrom(x => Mapper.Map<ICollection<Dependent>, ICollection<DependentDetail>>(x.Dependents)));

Dependent:

        public string Title { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string MiddleName { get; set; }
        public System.DateTime Dob { get; set; }
        public string Sex { get; set; }
        public string Relationship { get; set; }
        public string CreatedBy { get; set; }
        public string ModifiedBy { get; set; }
        public string DepartmentCode { get; set; }
        public string Address1 { get; set; }
        public string Address2 { get; set; }
        public string Address3 { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string MailCountry { get; set; }
        public string Zip { get; set; }
        public Nullable<System.DateTime> SsnEncryptDate { get; set; }

When Dependents is removed Subscriber maps perfectly

As for the Dependent Entity and Model they are copy and paste with all items public. It appears as if AutoMapper is trying to squeeze the collection into an int instead of the specified map.

Any Ideas?

Dependents is a navigation property

Edit : This was being tested in a functional test in an async method. Quick unit test has been created:

[TestMethod]
public  void RetrieveActiveMember()
{
    MemberEntity.Member Subscriber = new Member();
    ICollection<Dependent> Dependent = new List<Dependent>();
    Dependent.Add(new Dependent { HostCountry = "HOME" });
    Subscriber.Dependents = Dependent;

    var Mapped = AutoMapper.Mapper.Map<Member, MemberDetailDto>(Subscriber);

    Assert.IsNotNull(Mapped);
}

Error being returned now is Method 'Add' in type X does not have an implementation'

Property:
Dependents ---> System.TypeLoadException: Method 'Add' in type 'Proxy<System.Collections.Generic.ICollection`1[[MemberService.Dto.DependentDetailDto_MemberService_Version=1.0.0.0_Culture=neutral_PublicKeyToken=null]]_mscorlib_Version=4.0.0.0_Culture=neutral_PublicKeyToken=b77a5c561934e089>' from assembly 'AutoMapper.Proxies, Version=0.0.0.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005' does not have an implementation.

Changing The automapper config for the dependent to

CreateMap<ICollection<Dependent>, ICollection<DependentDetailDto>>()
                .ConstructUsing((ICollection<Dependent> Dependents) => {
                    List<DependentDetailDto> DependentList = new List<DependentDetailDto>();
                    foreach (var Dependent in Dependents)
                        DependentList.Add(new DependentDetailDto { });
                return DependentList;
            });

Makes the unit test work albeit no longer actually using Automapper which is a big caveat, however it still breaks on the functional test

I can't think of anything else to add as Dependents does not even have an integer field

Addendum: The entity, the Dto, and the caller are all in different libraries but I have not been able to replicate it in .NETFiddle

Upvotes: 3

Views: 4847

Answers (2)

SCFi
SCFi

Reputation: 522

Did not figure out the root cause of the issue, but found a fix.

Changed the MemberDto property Dependents name to Dependentss and it worked. Changing it back breaks it again. I should add there is no other Dependents property on either object.

I have no idea but the name appears to be what was breaking it.

Upvotes: 1

Georg Patscheider
Georg Patscheider

Reputation: 9463

Automapper should normally handle collections for you. It will also look up any known maps that might apply, so no need to call Mapper.Map inside a MapFrom.

Just define the maps for individual entities:

CreateMap<Dependent, DependentDetailDto>();
CreateMap<Member, MemberDetailDto>()
    .ForMember(dto => dto.Dependents, o => o.MapFrom(src => src.Dependents);

Upvotes: 2

Related Questions