priyanka.sarkar
priyanka.sarkar

Reputation: 26528

How to use ForMember properly inside a collection?

I have my source class as

public class SourceEmployee
    {
        public int EmployeeID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public List<ResidentialAddress> EmployeeResidences { get; set; }
    }

and the ResidentialAddress is as under

public class ResidentialAddress
    {
        public string State { get; set; }
        public string City { get; set; }
        public int ZipCode { get; set; }

    }

The Destination class is as under

public class DestinationEmployee
{
        public int EmployeeID { get; set; }
        public string FullName { get; set; }       
        public List<ResidentialAddress1> Address { get; set; }

}

public class ResidentialAddress1
{
   public string FullAddress { get; set; }
}

How to perform the ForMember for the FullAddress which will be State + City + ZipCode ?

I am lost after

Mapper.CreateMap<SourceEmployee, DestinationEmployee>();

Mapper.CreateMap<SourceEmployee, DestinationEmployee>().
ForMember(f => f.FullName, f => f.MapFrom(a => string.Concat(a.FirstName, " ", a.LastName)))
.ForMember(x => x.EmployeeResidences1, x => x.MapFrom(y => string.Concat(y.EmployeeResidences.m, " ", y.LastName)));

Upvotes: 2

Views: 281

Answers (2)

Red
Red

Reputation: 2776

You should have a separate map profile for your ResidentialAddress -> ResidentialAddress1 transformation. When your parent object will be transformed using automapper, all child objects will get transformed using defined map profiles:

Mapper.CreateMap<SourceEmployee, DestinationEmployee>()
    .ForMember(f => f.FullName, f => f.MapFrom(a => string.Concat(a.FirstName, " ", a.LastName)))
    .ForMember(x => x.Address, x => x.MapFrom(y => y.EmployeeResidences)));

Mapper.CreateMap<ResidentialAddress, ResidentialAddress1>
    .ForMember(x => x.FullAddress, map=>map.From(from => string.Format("{0} {1} {2}", from.State, from.City, from.ZipCode);

This way if in code you will have to transform ResidentialAddress to ResidentialAddress1 in multiple places, you won't have to add any code, just use Mapper.Map<>.

I also suggest you to switch to profiles, instead of defining your mapper configurations inline: https://github.com/AutoMapper/AutoMapper/wiki/Configuration

Upvotes: 1

Fabjan
Fabjan

Reputation: 13676

Well, you can use LINQ to let AutoMapper know how to map 3 properties into one property and you shouldn't really use Mapper.CreateMap() as it is deprecated and will not be supported from version 5.0 - use Mapper.Initialize() instead.

Let's have a look at this example :

            Mapper.Initialize(cfg =>
            {
                cfg.CreateMap<SourceEmployee, DestinationEmployee>();

                cfg.CreateMap<SourceEmployee, DestinationEmployee>()
                .ForMember(f => f.FullName, f => f.MapFrom(a => string.Concat(a.FirstName, " ", a.LastName)))
                .ForMember(
                    x => x.Address,
                    x => x.MapFrom(
                        y => y.EmployeeResidences.Select(
                            r => new ResidentialAddress1()
                            {
                                FullAddress = String.Concat(
                                    r.State, "  ", r.City, "  ", r.ZipCode)
                            }).ToList()));
            });

            SourceEmployee emp = new SourceEmployee()
            {
                EmployeeID = 1,
                FirstName = "Alex",
                LastName = "Green",
                EmployeeResidences = new List<ResidentialAddress>()
                {
                    new ResidentialAddress() { State = "abc", City = "def", ZipCode = 110 },
                    new ResidentialAddress() { State = "foo", City = "qwe", ZipCode = 220 },
                    new ResidentialAddress() { State = "bar", City = "ert", ZipCode = 330 },
                }
            };

            var sourceEmp = Mapper.Map<SourceEmployee, DestinationEmployee>(emp);

            Console.WriteLine(sourceEmp.Address.Count);    
            Console.WriteLine(sourceEmp.Address[1].FullAddress);

Output :

3
foo qwe 220

Upvotes: 2

Related Questions