Cómo especificar la regla de mapeo cuando los nombres de las propiedades difieren

144

Soy un novato en el marco de Automapper. Tengo una clase de dominio y una clase DTO de la siguiente manera:

public class Employee
{
   public long Id {get;set;}
   public string Name {get;set;}
   public string Phone {get;set;}
   public string Fax {get;set;}
   public DateTime DateOfBirth {get;set;}
}

public class EmployeeDto
{
   public long Id {get;set;}
   public string FullName {get;set;}
   public DateTime DateOfBirth {get;set;}
}

Nota: El nombre de la propiedad " Nombre " de la Employeeclase no es el mismo que el de la propiedad " Nombre completo " de la EmployeeDtoclase.

Y aquí está el código para asignar el Employeeobjeto a EmployeeDto:

Mapper.CreateMap<Employee, EmployeeDto>(); // code line (***)
EmployeeDto dto = Mapper.Map<Employee, EmployeeDto>(employee); 

Mi pregunta es: si quiero asignar Employee(clase de origen) a EmployeeDto(clase de destino), ¿cómo puedo especificar la regla de asignación? En otras palabras, ¿cómo debo hacer más con la línea de código (***) anterior?

Thomas.Benz
fuente

Respuestas:

292

No importa, yo mismo encontré una solución:

Mapper.CreateMap<Employee, EmployeeDto>()
    .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => src.Name));
Thomas.Benz
fuente
1
¿Hay alguna forma de especificarlo globalmente para cualquier clase, algo como prefijo / sufijo? Por ejemplo, tengo un montón de clases para una biblioteca que tiene la propiedad "Localizaciones" cada una. Y quiero asignarlos a clases donde la propiedad correspondiente se llama "LocalizedName". ¿Mi única opción es agregar ForMember a cada configuración de mapeo?
NickAb
2
no hay ningún método CreateMap en la clase Mapper :(
Navid_pdp11
3
@ Navid_pdp11 sí lo hay. Necesitas tener la clase estática Mapper no una instancia
Jordy van Eijk
@JordyvanEijk ¿Qué versión está utilizando que tenga un método estático "CreateMap"? En 5.1.1.0 no existe tal cosa
Matt Thomas el
66
@MattThomas Después de echar un vistazo al github de automapper, veo que a partir de la versión 5.0 CreateMap está obsoleto y dicen que debe usar MapperConfiguration o Mapper.Initialize.
Jordy van Eijk
7

Solo para incluir los comentarios anteriores en un enfoque actualizado usando Automapper 8.1 + ...

var mapConfig = new MapperConfiguration(
   cfg => cfg.CreateMap<Employee, EmployeeDto>()
      .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => src.Name))
);

Entonces construirías el mapeador usando mapConfig:

var mapper = mapConfig.CreateMapper();
ebol2000
fuente
2

También podemos especificar en los atributos de clase para el mapeo

De https://docs.automapper.org/en/stable/Conventions.html#attribute-support

Soporte de atributos

AddMemberConfiguration().AddName<SourceToDestinationNameMapperAttributesMember>(); * Actualmente siempre está encendido

Busca instancias de SourceToDestinationMapperAttribute para Propiedades / Campos y llama a la función isMatch definida por el usuario para encontrar coincidencias de miembros.

MapToAttribute es uno de ellos que coincidirá con la propiedad según el nombre proporcionado.

public class Foo
{
    [MapTo("SourceOfBar")]
    public int Bar { get; set; }
}
Pranay DevOps
fuente
Al citar el contenido de otro lugar literalmente, asegúrese de utilizar el formato de comillas en bloque para dejar en claro a los lectores que el contenido se copia.
TylerH
Compruebe el nuevo estilo :) docs.automapper.org/en/latest/Attribute-mapping.html
Lucian Bargaoanu
Muy nuevo para stackoverflow. Seguro seguirá las reglas @TylerH
Pranay DevOps