I am trying to map the below class to a destination class using the below code. Here trying to map Employee class to
static void Main(string[] args)
{
var emp = new List<Employee>()
{
new Employee()
{
FirstName = "Test",
LastName = "Performance",
ID="1",
Availabities = new List<Availability>()
{
new Availability()
{
BeginDate = DateTime.Now,
EndDate = DateTime.Now.AddDays(1)
}
}
},
new Employee()
{
FirstName = "Test1",
LastName = "Performance1",
ID="2",
Availabities = new List<Availability>()
{
new Availability()
{
BeginDate = DateTime.Now,
EndDate = DateTime.Now.AddDays(10)
}
}
},
new Employee()
{
FirstName = "Test123",
LastName = "Performance1",
ID="3",
Availabities = new List<Availability>()
{
new Availability()
{
BeginDate = DateTime.Now,
EndDate = DateTime.Now.AddDays(5)
},
new Availability()
{
BeginDate = DateTime.Now,
EndDate = DateTime.Now.AddDays(3)
}
}
}
};
Here is the destination object mapping, here the Employee to be mapped with EmployeeDest.
List<AvailabilityDest> empAvailabilitiesDest = new List<AvailabilityDest>();
var results = new List<EmployeeDest>();
foreach (var token in emp)
{
empAvailabilitiesDest.Clear();
foreach (var item in token.Availabities)
{
var empAvailability = new AvailabilityDest
{
BeginDateDest = item.BeginDate,
EndDateDest = item.EndDate,
};
empAvailabilitiesDest.Add(empAvailability);
}
var employee = new EmployeeDest
{
FirstNameDest = token.FirstName,
LastNameDest = token.LastName,
IDDest =token.ID,
AvailabitiesDest = empAvailabilitiesDest
};
results.Add(employee);
}
Console.WriteLine(results);
}
Here the empAvailabilitiesDest.Clear() is not clearing the list and the availabilityDest is getting increased with each iteration.
I am missing something here .
Presumably the real problem here is that all your employee objects are sharing the same list; it doesn't matter whether you clear it, add things, etc: if there's one list and it is shared between all the employees, then changes to that list will show against every employee, and it will appear incorrect.
Presumably, you really just want to move the list creation to inside the foreach per employee:
var results = new List<EmployeeDest>();
foreach (var token in emp)
{
List<AvailabilityDest> empAvailabilitiesDest = new List<AvailabilityDest>
();
// your previous code unchanged
}
1. Problem in your code
var employee = new EmployeeDest
{
FirstNameDest = token.FirstName,
LastNameDest = token.LastName,
IDDest = token.ID,
AvailabitiesDest = empAvailabilitiesDest // This is problematic code
};
Due to above code, every empolyee.AvailabitiesDest will reference to the same object because it is not a primitive type variable. You have to assign a copy of the object to employee.AvailabitiesDest,
var employee = new EmployeeDest
{
FirstNameDest = token.FirstName,
LastNameDest = token.LastName,
IDDest = token.ID,
AvailabitiesDest = new List<AvailabilityDest>(empAvailabilitiesDest)
};
2. Simplifying code
Use Linq.
results = emp.Select(token => new EmployeeDest
{
FirstNameDest = token.FirstName,
LastNameDest = token.LastName,
IDDest = token.ID,
AvailabitiesDest = token.Availabities.Select(item => new AvailabilityDest
{
BeginDateDest = item.BeginDate,
EndDateDest = item.EndDate,
}).ToList()
}).ToList();
Or use AutoMapper
var mapper = new Mapper(new MapperConfiguration(cfg =>
{
cfg.CreateMap<Employee, EmployeeDest>()
.ForMember(x => x.FirstNameDest, opt => opt.MapFrom(src => src.FirstName))
.ForMember(x => x.LastNameDest, opt => opt.MapFrom(src => src.LastName))
.ForMember(x => x.IDDest, opt => opt.MapFrom(src => src.ID))
.ForMember(x=> x.AvailabitiesDest, opt => opt.MapFrom(src => src.Availabities));
cfg.CreateMap<Availability, AvailabilityDest>()
.ForMember(x => x.BeginDateDest, opt => opt.MapFrom(src => src.BeginDate))
.ForMember(x => x.EndDateDest, opt => opt.MapFrom(src => src.EndDate));
}));
var results = mapper.Map<List<EmployeeDest>>(emp);