how to construct a ViewModel

entity-framework viewmodel

Question

I've included EF 4 into the project. There are tables for orders and customers inside. This has a connection between one (client) and many (order).

For both (CustomerViewModel and OrderViewModel) to be sent from my domain layer to interface layer, I'm developing a viewmodel (MVC in this case).

Do I need to reference both viewmodels, you ask? like in the customerviewmodel, whichIEnumerable<OrderViewModel> Furthermore, orderviewmodel hasCustomerViewModel . If so, how can I create it in such a way (as a best practice)?IEnumerable<OrderViewModel> and CustomerViewModel has the right reference filled in?

1
8
4/10/2012 6:55:09 PM

Accepted Answer

I would never create a view model from the perspective of the domain model (i.e., the entities), but rather with a particular view in mind. What you want to show and what you want to change in a view will determine how a viewmodel appears.

Because of this, you lack THEOrderViewModel both THECustomerViewModel because you may show or update an order, a customer, or just a portion of them using multiple views. As a result, you have those ViewModels several times in various variants, each for a distinct purpose and view.

Let's say you have anOrderEditView and this view will let you change order details and show the order's customer. There would be anOrderEditViewModel as in this:

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; }
    // ...
}

This OrderEditCustomerViewModel does not need a mention ofOrderEditViewModel .

You may fill up this ViewModel as follows:

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();

Conversely, if you own aCustomerEditView which permits modification of customer data and displays the client's orders, the viewmodel may be

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; }
    // ...
}

Here CustomerEditOrderViewModel does not need a mention ofCustomerEditViewModel Then you can build the ViewModel using the database in the following manner, for instance:

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();

The Customer(*)ViewModel the and SOrder(*)ViewModel Depending on the view in which they are used, s have varied requirements for the attributes, references, and data annotations.

With these factors in mind, the issue of mutually acceptable references between theOrderViewModel both theCustomerViewModel vanishes since your views often don't need such a bidirectional reference.

26
4/4/2012 11:49:32 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow