2010-01-24 67 views
18

Me preguntaba si es posible mapear múltiples objetos DTO a un solo objeto ViewModel utilizando Automapper?¿Es posible mapear múltiples objetos DTO en un solo modelo de vista usando Automapper?

Básicamente, tengo varios objetos DTO y me gustaría mostrar información de cada uno en una sola pantalla en ASP.NET MVC 2.0. Para hacerlo, me gustaría aplanar los objetos DTO (o partes de ellos ...) en el modelo View y pasar dicho modelo de vista a la vista. Si tuviera un DTO esto sería fácil, pero nunca lo he visto con múltiples. Obviamente hay una serie de formas indirectas de hacer esto (fuera de Automapper), pero este es el enfoque que me gustaría tomar si es posible.

+0

puede con el ValueInjecter http://valueinjecter.codeplex.com/documentation – Omu

Respuesta

7

Puede crear un DTO compuesto que contenga dos o más objetos DTO y asignar el DTO compuesto al modelo de vista de salida.

+1

Esto es lo que hemos hecho, y encontré que funciona mejor. Ese objeto de presentación compuesto tiende a comenzar a contener el comportamiento, etc. relacionado con los objetos compuestos. –

+2

Comencé a seguir esa ruta pero luego me di cuenta de que si tenía que mapear manualmente un objeto compuesto antes de poder mapear <>(), entonces ¿qué es lo que este paso extra me proporciona? Siguiendo este enfoque, se asegura de que todas las asignaciones de objetos se administren a través de AutoMapper, pero luego las viva con la excepción de las asignaciones manuales a las compuestas. No me opongo completamente a la idea, solo digo ... – tbehunin

+0

Estoy de acuerdo. La solución que acaba de publicar Gordon Nongkynrih me parece mucho más elegante. –

13
+0

Aunque muy tarde en este hilo ;-), muchas gracias por este enlace. ¡Estoy comenzando con AutoMapper y me habría encontrado con este problema muy pronto! ¡Voto! :-) –

+0

Gracias. Sabía que es bastante tarde en el hilo, pero se ha enfrentado al mismo problema recientemente. Me doy cuenta de que nunca es demasiado tarde para actualizar incluso el hilo viejo :) – Bahdeng

+5

Supongo que no fue archivado por mucho tiempo ... Ya no está disponible ... – KDT

4

se puede añadir un método de extensión Mapa de anulación fuera IMappingEngine que tiene una matriz params. Algo así como:

public static class AutoMapperExtensions 
{ 
    public static T Map<T>(this IMappingEngine engine, params object[] sources) where T : class 
    { 
     if (sources == null || sources.Length == 0) 
      return default(T); 

     var destinationType = typeof (T); 
     var result = engine.Map(sources[0], sources[0].GetType(), destinationType) as T; 
     for (int i = 1; i < sources.Length; i++) 
     { 
      engine.Map(sources[i], result, sources[i].GetType(), destinationType); 
     } 

     return result; 
    } 
} 

A continuación, puede llamar así:

var result = Mapper.Engine.Map<MyViewModel>(dto1, dto2, dto3); 
7

Si usted tiene 2 clases DTO y 1 aplastado vista del modelo:

public class Dto1 
{ 
    public string Property1 { get; set; } 
} 
public class Dto2 
{ 
    public string Property2 { get; set; } 
} 
public class FlattenedViewModel 
{ 
    public string Property1 { get; set; } 
    public string Property2 { get; set; } 
} 

Y se crea asignaciones para tanto DTOs para ver el modelo:

CreateMap<Dto1, FlattenedViewModel>(); 
CreateMap<Dto2, FlattenedViewModel>(); 

Puede asignar primero DTO al modelo y luego simplemente "añadir" segunda DTO:

var dto1 = new Dto1 { Property1 = "Value1"; } 
var dto2 = new Dto2 { Property2 = "Value2"; } 

var model = Mapper.Map<FlattenedViewModel>(dto1); // map dto1 properties 
Mapper.Map(dto2, model); // append dto2 properties 
0

Hace poco trabajé en esto a mí mismo y tener una gran solución. Lo más probable es que sus dos vistas estén relacionadas de alguna manera en su sistema (especialmente si está utilizando Entity Framework). Verifica tus modelos y deberías ver algo que muestre la relación, si no lo haces, simplemente agrégalo. (Los virtual)

Sus modelos

public class Dto1 
    { 
     public int id { get; set; } 
     public string Property2 { get; set; } 
     public string Property3 { get; set; } 
     public string Property4 { get; set; } 
     public string Property5 { get; set; } 

     public virtual Dto2 dto2{ get; set; } 

    } 

    public class Dto2 
    { 
     public int id { get; set; } 
     public string PropertyB { get; set; } 
     public string PropertyC { get; set; } 
     public string PropertyD { get; set; } 
     public string PropertyE { get; set; } 
    } 

Sus ViewModels

public class Dto1ViewModel 
    { 
     public string Property1 { get; set; } 
     public string Property2 { get; set; } 

     public virtual Dto2VMForDto1 dto2{ get; set; } 
    } 

//Special ViewModel just for sliding into the above 
    public class Dto2VMForDto1 
    { 
     public int id { get; set; } 
     public string PropertyB { get; set; } 
     public string PropertyC { get; set; } 
    } 

AutoMapper se ve así:

 cfg.CreateMap< Dto1, Dto1ViewModel>(); 
     cfg.CreateMap< Dto2, Dto2VMForDto1 >(); 

Asumo que está recibiendo sus datos con LinQ:

Dto1ViewModel thePageVM = (from entry in context.Dto1 where...).ProjectTo<Dto1ViewModel>(); 

Viola, todo funcionará. En su vista simplemente acceda usando model.dto2.PropertyB

Cuestiones relacionadas