Reputation: 1188
How to setup automapper to the next scenario works properly?
using AutoMapper;
using System;
using System.Collections.Generic;
namespace ConsoleApplication5
{
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Company
{
public int Id { get; set; }
public string Name { get; set; }
public List<Employee> Employees { get; set; }
}
public class Country
{
public List<Company> Companies { get; set; }
public List<Employee> Employees { get; set; }
}
public class EmployeeDto
{
public int Id { get; set; }
public string Name { get; set; }
}
public class CompanyDto
{
public int Id { get; set; }
public string Name { get; set; }
public List<EmployeeDto> Employees { get; set; }
}
public class CountryDto
{
public List<CompanyDto> Companies { get; set; }
public List<EmployeeDto> Employees { get; set; }
}
class Program
{
static void Main(string[] args)
{
// mapper set up
Mapper.Initialize((cfg) =>
{
cfg.CreateMap<Country, CountryDto>();
cfg.CreateMap<Company, CompanyDto>();
cfg.CreateMap<Employee, EmployeeDto>();
});
// data
var company = new Company
{
Id = 1,
Name = "Blah",
Employees = new List<Employee> {
new Employee { Id = 1, Name = "John" },
new Employee { Id = 2, Name = "Mary" },
}
};
var country = new Country { Companies = new List<Company> { company } };
country.Employees = company.Employees;
// mapping
var dto = Mapper.Map<CountryDto>(country);
//print
dto.Companies[0].Employees[0].Id = 100;
Console.WriteLine("{0} - {1}", dto.Companies[0].Employees[0].Id, dto.Employees[0].Id); // should be the same
Console.WriteLine(dto.Companies[0].Employees[0].Id == dto.Employees[0].Id); // should be true
Console.WriteLine("End");
Console.ReadLine();
}
}
}
basically I want to change some property in my first DTO list and that changes should reflect to the same list, but in another porperty.
ps: when I'm using my domain entities is working fine!
Upvotes: 4
Views: 935
Reputation: 3453
This is not a problem of automapper, but rather the design of your classes.
Automapper has no idea that CountryDto.Employees
and CountryDto.Companies.Employees
are meant to be the same, furthermore, developers reading your code will know that as well - because of the way the classes are designed.
Automapper just creates a new List<EmployeeDto>
for every List<Employee>
The fact that the collections match in domain entity is because you set one collection reference to be equal to the other
country.Employees = company.Employees;
However, they are NOT equal by design, they are two different references. They are only equal because of how they are initialized.
What is the purpose of this design?
If you would like to list all employees of all companies on a country object - you have to define a calculated property (or better, a method) that would aggregate the fields from countries, for example using select many
However, putting a calculation property on DTO is not a good design choice. Please describe more what you are trying to achieve, so I can suggest a better design.
Upvotes: 2