2012-06-05 13 views
9

Sé que hay una gran cantidad de mensajes sobre el tema, pero no puedo encontrar uno que me ayuda a hacer lo que quiero. Sé que eventualmente usaré Automapper, pero antes de comenzar a jugar con él, quiero aprender a hacer las cosas manualmente. Quiero crear un modelo de vista, rellenarlo con los valores de mis entidades a través de un repositorio y enviarlo a mi punto de vista. Tan simple como suena, estoy luchando para lograrlo. Estoy usando MVC 3, EF 4.3, Base de datos primero. He autogenerado mis clases. Estoy poniendo las entidades competentes (abreviada/renombrado para este post) y clases, esto es lo que tengo hasta ahora:¿Cómo poblar manualmente ViewModel (No usar AutoMapper!)

agregado Entidad: Cabecera de envío

using System; 
using System.Collections.Generic; 

namespace My.Models 
{ 
public partial class ShippingHdr 
{ 
    public ShippingHdr() 
    { 
     this.ShippingLI = new HashSet<ShippingLI>(); 
    } 

    public int ID { get; set; } 
    public int ShipToSiteID { get; set; } 
    public Nullable<System.DateTime> DateShipped { get; set; } 
    public Nullable<System.DateTime> EstDeliveryDate { get; set; } 
    public string FromSitePOC { get; set; } 
    public Nullable<int> ShipperID { get; set; } 
    public string TrackingNo { get; set; } 
    public string Comments { get; set;} 
    public virtual Shippers Shippers { get; set; } 
    public virtual ICollection<ShippingLI> ShippingLI { get; set; } 
} 

} 

Aquí está mi modelo de vista

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

namespace My.Models.ViewModels 
{ 

public class ShippingHeaderSummaryVM 
{ 
    public int ID { get; set; } 
    public string Site { get; set; } 
    public Nullable<System.DateTime> DateShipped { get; set; } 
    public Nullable<System.DateTime> EstDeliveryDate { get; set; } 
    public string TrackingNo { get; set; } 
    public string HeaderComments { get; set; } 
    public string Shipper { get; set; } 
    public int NumOrders { get; set; } 
    public string Site { get; set; } 


} 

}

Aquí es una consulta que tengo que devolver los artículos que desea utilizar para rellenar mi modelo de vista con. Creo que el mejor lugar para esto es en un repositorio. Verifiqué que devuelve los datos que quiero usando LinqPad (de ahí la referencia que falta a mi dbContxt). Sólo que no sé cómo llegar a los valores de la consulta al modelo de vista:

var shipments = from h in c.ShippingHdrs 
         where (h.ShippingLI.Count > 1) 
         join 
         e in c.vHr_Employees on h.CreatedBy equals e.ID 
         join 
         s in c.Shippers on h.ShipperID equals s.ShipperID 
         join 
         r in vAaiomsSites on h.ShipToSiteID equals r.SiteID 

         select new 
         { 
          h.ID, 
          r.Site, 
          h.EstDeliveryDate, 
          h.DateShipped, 
          h.TrackingNumber, 
          h.HeaderComments, 
          e.LastName, 
          h.ShippingLI.Count, 
          s.Shipper 
                 }; 

Así que lo que quiero hacer, de nuevo sin usar AutoMapper, es poblar el modelo de vista con todas las filas de la ShippingHdr entidad y pasarlo a mi punto de vista.

Éstos son los filelds que necesitan ser asignada:

ShippingHeaderSummaryVM asignada desde envíos

ID = h.ID 
Site = r.Site 
DateShipped = h.DateShipped 
EstDeliveryDate = h.EstDeliveryDate 
TrackingNo = h.TrackingNumber 
FromSitePOC = e.LastName 
NumOrders = h.ShippingLI.Count 
Shipper = s.Shipper 
HeaderComments = h.HeaderComments 

estoy atascado aquí. ¿Cómo pueblan el modelo de vista de la consulta? ¿Cómo puedo llamar esa acción desde mi controlador?

espero haber dado suficiente información, cualquier ayuda se agradece.

+0

Consejo, en lugar de 'anulable ' sólo puede ir '' DateTime –

+0

Usted debe ser capaz de decir 'select nueva ShippingHeaderSummaryVM {}? ', ¿esta es su salida en lugar de usar la carpeta modelo para la entrada? –

+0

@Lavinski, acabo de copiar/pegar las entidades generadas para esta publicación, realmente no entiendo por qué algunas se generaron con Nullable mientras que otras no. Pensé que coincidiría con mis tablas de SQL permiten nulo pero no lo hizo. –

Respuesta

5

Con el fin de rellenar una lista de los envíos en base a su objeto vista del modelo que se necesitan para crear un método de mapeo para mapear desde su colección de envíos desde su base de datos a una colección de envíos basado en el modelo de vista:

var model = new List<ShippingHeaderSummaryVM>(); 

foreach(var h in shipments) 
{ 

    var viewModel = new ShippingHeaderSummaryVM 
    { 
    ID = h.ID 
    Site = r.Site 
    DateShipped = h.DateShipped 
    EstDeliveryDate = h.EstDeliveryDate 
    TrackingNo = h.TrackingNumber 
    FromSitePOC = e.LastName 
    NumOrders = h.ShippingLI.Count 
    Shipper = s.Shipper 
    HeaderComments = h.HeaderComments 
    } 

    model.Add(viewModel); 
} 

return model; 

Como nota al margen, esto se convierte en un chiste después de que haya AutoMapper en funcionamiento:

var model = Mapper.Map<IEnumerable<ShippingHdr>, IEnumerable<ShippingHeaderSummaryVM>>(shipments); 

Mientras, el aprendizaje de cómo hacer las cosas de forma manual es grande. Manualmente mapear modelos realmente no lo beneficia de ninguna manera. Ve con AutoMapper.

+1

Tengo la intención de ir con Automapper, simplemente siento que realmente necesito entender la mecánica. No puedo esperar para probar esto. gracias –

+0

cuando dices que el mapeo manual no proporciona ningún beneficio, he leído un artículo [enlace] http://www.devtrends.co.uk/blog/stop-using-automapper-in-your-data-access- código que dice que al usar Automapper, se lee todo el modelo antes de que se realice la asignación. Además de usar el complemento que creó, parece una posible razón para mapear manualmente si hay un problema de rendimiento. Los usuarios de mi aplicación están utilizando el servicio de Internet por satélite y la latencia es un asesino, estoy buscando reducir el acceso a la base de datos tanto como sea posible. ¿Automapper no traería más de lo que necesito? –

+0

Las "asignaciones" en sí mismas que utilizan el autoaprendizaje generalmente se crean dentro de la sección OnApplicationStarted del método Global.asax. Dentro de esta configuración, puede decirle a Automapper qué campos desea tomar de su entidad de dominio a su modelo de vista. Según mi experiencia, el rendimiento de Automapper no es diferente al de un mapeo manual y encuentro que mi código es más limpio y más fácil de seguir. OMI: los beneficios que el Automapper trae a la mesa pesan un impacto muy, muy insignificante (si corresponde). ¡También puedes poner a prueba tu mapeo! – Jesse

1

También puede utilizar LINQ para hacer algo como esto ...

shipments.Select(h => new ShippingHeaderSummaryVM(){ 
    ID = h.ID, 
    Site = r.Site, 
    DateShipped = h.DateShipped, 
    EstDeliveryDate = h.EstDeliveryDate, 
    TrackingNo = h.TrackingNumber, 
    FromSitePOC = e.LastName, 
    NumOrders = h.ShippingLI.Count, 
    Shipper = s.Shipper, 
    HeaderComments = h.HeaderComments 
}); 

Tenga en cuenta que durante la visión de mapeo modelos es grande para pasar a una vista, siempre lo hacen de forma manual durante la lectura de un modelo de vista para actualizar tu base de datos

Editar: Gracias por la corrección de errata :-)

Cuestiones relacionadas