32

I am using automapper to map source and destination objects. While I map them I get the below error.

Expression must resolve to top-level member. Parameter name: lambdaExpression

I am not able resolve the issue.

My source and destination objects are:

public partial class Source
{
        private Car[] cars;

        public Car[] Cars
        {
            get { return this.cars; }
            set { this.cars = value; }
        }
}

public partial class Destination
{
        private OutputData output;

        public OutputData Output
        {            
            get {  return this.output; }
            set {  this.output= value; }
        }
}

public class OutputData
{
        private List<Cars> cars;

        public Car[] Cars
        {
            get { return this.cars; }
            set { this.cars = value; }
        }
}

I have to map Source.Cars with Destination.OutputData.Cars object. Could you please help me in this?

Rob Hruska
  • 118,520
  • 32
  • 167
  • 192
  • 1
    Could you add automapper configuration? – k0stya Jul 24 '12 at 19:54
  • I tried to add the configuration, it throws error while running the configurations. My configuration looks as below Mapper.CreateMap().ForMember( dest => dest.OutputData.Cars, input => input.MapFrom(i => i.Cars)); Expression 'dest => dest.OutputData.Cars' must resolve to top-level member. Parameter name: lambdaExpression – Sandeep Reddy Pinniti Jul 25 '12 at 06:34
  • This worked for me: `Mapper.CreateMap().ForMember(x => x.Cars, x => x.MapFrom(y => y.OutputData.Cars)).ReverseMap();` (also posted in an answer below) – Dominus.Vobiscum Jan 14 '20 at 20:37
  • https://stackoverflow.com/questions/15554788/deep-level-mapping-using-automapper related – KushalSeth Mar 15 '22 at 10:03

6 Answers6

49

You are using :

 Mapper.CreateMap<Source, Destination>()
 .ForMember( dest => dest.OutputData.Cars, 
             input => input.MapFrom(i => i.Cars)); 

This won't work because you are using 2 level in the dest lambda.

With Automapper, you can only map to 1 level. To fix the problem you need to use a single level :

 Mapper.CreateMap<Source, Destination>()
 .ForMember( dest => dest.OutputData, 
             input => input.MapFrom(i => new OutputData{Cars=i.Cars})); 

This way, you can set your cars to the destination.

Patrick Desjardins
  • 136,852
  • 88
  • 292
  • 341
  • Also used this solution for mapping between objects where the source had `string somethingKey` and `string somethingValue`, and the destination had `object something { string Key, string Value }` – st3inn Jan 10 '13 at 14:13
  • Greate Answer!! – Ricardo Nov 19 '16 at 15:07
18

You can do it that way:

// First: create mapping for the subtypes
Mapper.CreateMap<Source, OutputData>();

// Then: create the main mapping
Mapper.CreateMap<Source, Destination>().
    // chose the destination-property and map the source itself
    ForMember(dest => dest.Output, x => x.MapFrom(src => src)); 

That's my way to do that ;-)

Marcus.D
  • 679
  • 6
  • 7
17
  1. Define mapping between Source and OutputData.

    Mapper.CreateMap<Source, OutputData>();
    
  2. Update your configuration to map Destination.Output with OutputData.

    Mapper.CreateMap<Source, Destination>().ForMember( dest => dest.Output, input => 
        input.MapFrom(s=>Mapper.Map<Source, OutputData>(s))); 
    
k0stya
  • 4,267
  • 32
  • 41
  • I have field in the OutputData which has some default value. I don't have a mapping for this field in the source. So I didn't map it. After mapping is done, my default value is set to null value on the destination. How to avoid it setting to a null value. – Sandeep Reddy Pinniti Jul 26 '12 at 10:38
6

ForPath works for this exact scenario.

Mapper.CreateMap<Destination, Source>().ForPath(dst => dst.OutputData.Cars, e => e.MapFrom(src => src.Cars));
Vijayanand Settin
  • 826
  • 11
  • 13
2

This worked for me:

Mapper.CreateMap<Destination, Source>()
    .ForMember(x => x.Cars, x => x.MapFrom(y => y.OutputData.Cars))
    .ReverseMap();
Dominus.Vobiscum
  • 702
  • 1
  • 9
  • 16
0

The correct answer given by allrameest on this question should help: AutoMapper - Deep level mapping

This is what you need:

Mapper.CreateMap<Source, Destination>()
    .ForMember(dest => dest.OutputData, opt => opt.MapFrom(i => i));
Mapper.CreateMap<Source, OutputData>()
    .ForMember(dest => dest.Cars, opt => opt.MapFrom(i => i.Cars));

When using the mapper, use:

var destinationObj = Mapper.Map<Source, Destination>(sourceObj)

where destinationObj is an instance of Destination and sourceObj is an instance of Source.

NOTE: You should try to move away from using Mapper.CreateMap at this point, it is obsolete and will be unsupported soon.

Community
  • 1
  • 1
Kevat Shah
  • 119
  • 1
  • 12