2012-03-27 22 views
7

Tengo EF 4 implementado en el proyecto. Dentro de él, hay tablas cliente y orden. Que tiene relación uno (cliente) a muchos (orden).cómo diseñar ViewModel

Estoy creando un modelo de vista para que ambos (CustomerViewModel y OrderViewModel) pasen de mi capa de dominio a capa de interfaz (MVC en este caso).

Ahora la pregunta es "¿Es necesario hacer referencia tanto viewmodel? Por ejemplo en customerviewmodel tiene IEnumerable<OrderViewModel> y en orderviewmodel tiene CustomerViewModel. Si es así ¿Cómo diseño que (como una buena práctica) para que IEnumerable<OrderViewModel> y CustomerViewModel se rellena con la referencia correcta?

+0

Vea si esto ayuda: http://blogs.teamb.com/craigstuntz/2009/12/31/38500/ –

+0

lo siento no relevante .. – user384080

Respuesta

23

Siempre conduciré el diseño de ViewModels con la vista específica en mente, nunca desde el punto de vista del modelo de dominio (= las entidades). La apariencia de un ViewModel depende de lo que desea visualizar y de desea modificar en una vista.

Como resultado, usted no tiene THE OrderViewModel y THE CustomerViewModel porque tiene diferentes vistas que mostrarán o editarán un pedido o cliente o partes de estos. Por lo tanto, tiene esos ViewModels para un propósito y una vista específicos y, por lo tanto, varias veces en diferentes variaciones.

Supongamos que tiene un OrderEditView y esta vista le permitirá editar la información del pedido y mostrar el cliente de ese pedido. Se podría tener una OrderEditViewModel así:

public class OrderEditViewModel 
{ 
    public int OrderId { get; set; } 

    public DateTime? ShippingDate { get; set; } 

    [StringLength(500)] 
    public string Remark { get; set; } 
    //... 

    public OrderEditCustomerViewModel Customer { get; set; } 
} 

public class OrderEditCustomerViewModel 
{ 
    [ReadOnly(true)] 
    public string Name { get; set; } 

    [ReadOnly(true)] 
    public string City { get; set; } 
    // ... 
} 

Este OrderEditCustomerViewModel no necesita una referencia a la OrderEditViewModel.

Puede rellenar este modelo de vista de este modo:

var orderEditViewModel = context.Orders 
    .Where(o => o.OrderId == 5) 
    .Select(o => new OrderEditViewModel 
    { 
     OrderId = o.OrderId, 
     ShippingDate = o.ShippingDate, 
     Remark = o.Remark, 
     Customer = new OrderEditCustomerViewModel 
     { 
      Name = o.Customer.Name, 
      City = o.Customer.City 
     } 
    }) 
    .SingleOrDefault(); 

Por otro lado, si usted tiene un CustomerEditView que permite que la información del cliente edición y muestra las órdenes del cliente en una lista, el modelo de vista podría ser:

public class CustomerEditViewModel 
{ 
    public int CustomerId { get; set; } 

    [Required, StringLength(50)] 
    public string Name { get; set; } 

    [Required, StringLength(50)] 
    public string City { get; set; } 
    //... 

    public IEnumerable<CustomerEditOrderViewModel> Orders { get; set; } 
} 

public class CustomerEditOrderViewModel 
{ 
    [ReadOnly(true)] 
    public DateTime? ShippingDate { get; set; } 

    [ReadOnly(true)] 
    public string Remark { get; set; } 
    // ... 
} 

Aquí CustomerEditOrderViewModel no necesita una referencia a la CustomerEditViewModel y se puede crear el modelo de vista de la base de datos de esta manera, por ejemplo:

var customerEditViewModel = context.Customers 
    .Where(c => c.CustomerId == 8) 
    .Select(c => new CustomerEditViewModel 
    { 
     CustomerId = c.CustomerId, 
     Name = c.Name, 
     City = c.City, 
     Orders = c.Orders.Select(o => new CustomerEditOrderViewModel 
     { 
      ShippingDate = o.ShippingDate, 
      Remark = o.Remark 
     }) 
    }) 
    .SingleOrDefault(); 

Los Customer(*)ViewModel s y los Order(*)ViewModel s son diferentes - en relación con las referencias necesarias, las propiedades y las anotaciones de datos, dependiendo de la vista en la que se utilizan.

Teniendo en cuenta estas consideraciones, la pregunta sobre las referencias correctas mutuas entre OrderViewModel y CustomerViewModel desaparece porque normalmente no necesita una referencia bidireccional para sus vistas.

+0

Slauma .. ¿Cómo se hace la asignación entre viewmodel a la entidad EF ¿y viceversa? – user384080

+0

también ... cómo rellenar public IEnumerable Orders {get; conjunto; } en CustomerEditViewModel? ¿haces perezoso o ansioso? – user384080

+0

@ user384080: el mapeo de la entidad EF a ViewModel son los dos fragmentos de código con el 'Seleccionar' (se llama" proyección "y ni la carga floja ni ansiosa, pero más cerca de la carga ansiosa excepto que solo recuperas las columnas del DB que realmente se necesitan para ViewModel, no para la entidad completa, que sería una sobrecarga innecesaria). Especialmente, el último fragmento también rellena la colección 'Pedidos' (consulte el' Seleccionar' interno). Para el camino de regreso de ViewModel a la entidad, uso DTOs, puede mapear manualmente las propiedades de ViewModel a DTO o usar una herramienta como AutoMapper. – Slauma