2012-03-27 23 views
7

Mam EF 4 wdrożony w projekcie. W jego ramach znajdują się stoły klienta i zamówienia. Który ma związek jeden (klient) do wielu (zamówienie).jak zaprojektować ViewModel

Tworzę model widoku dla obu (CustomerViewModel i OrderViewModel), które mają być przekazywane z mojej warstwy domeny do warstwy interfejsu (w tym przypadku MVC).

Teraz pytanie brzmi „czy muszę odwoływać się zarówno ViewModel? Na przykład w customerviewmodel ma IEnumerable<OrderViewModel> aw orderviewmodel ma CustomerViewModel. Jeśli tak, w jaki sposób zaprojektować go (jako najlepszej praktyki), tak że IEnumerable<OrderViewModel> i CustomerViewModel jest wypełniana poprawne odniesienie?

+0

Sprawdź, czy to pomaga: http://blogs.teamb.com/craigstuntz/2009/12/31/38500/ –

+0

Niestety nie dotyczy .. – user384080

Odpowiedz

23

Zawsze będę kierował projektem ViewModels z myślą o konkretnym widoku, nigdy z punktu widzenia modelu domeny (= obiektów). Jak wygląda ViewModel zależy od tego, co chcesz wyświetlić i co chcesz zmodyfikować w widoku:

W rezultacie nie masz THE OrderViewModel i THE CustomerViewModel, ponieważ masz różne widoki, które będą wyświetlać lub edytować zamówienie lub klienta lub ich części. Tak, masz te ViewModels dla określonego celu i widoku, a zatem wiele razy w różnych odmianach.

Załóżmy, że masz OrderEditView, a widok ten pozwoli na edycję informacji o zamówieniu i wyświetlenie klienta tego zamówienia. to masz OrderEditViewModel takiego:

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

Ten OrderEditCustomerViewModel nie potrzebuje odniesienie do OrderEditViewModel.

Można wypełnić tę ViewModel tak:

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

Z drugiej strony, jeśli masz CustomerEditView który pozwala informacje edycji klienta i wyświetla polecenia klienta na liście, ViewModel może być:

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

Tutaj CustomerEditOrderViewModel nie potrzebuje odniesienie do CustomerEditViewModel i można utworzyć ViewModel z bazy danych w ten sposób na przykład:

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

S Customer(*)ViewModel s i Order(*)ViewModel s są różne - dotyczące niezbędnych odniesień, właściwości i adnotacji danych, w zależności od widoku, w którym są używane.

Mając na uwadze powyższe rozważania, pytanie o wzajemne poprawne odniesienia między OrderViewModel i CustomerViewModel znika, ponieważ zwykle nie potrzebujesz takiego dwukierunkowego odniesienia dla swoich widoków.

+0

Slauma .. Jak zrobić mapowanie między viewmodelem do jednostki EF i wzajemnie? – user384080

+0

również .. jak wypełnić publiczne IEnumerable Orders {get; zestaw; } w CustomerEditViewModel? czy robisz leniwych czy chętnych? – user384080

+0

@ user384080: Mapowanie z elementu EF na ViewModel to dwa fragmenty kodu z opcją "Wybierz" (nazywa się to "rzutowaniem" i nie są ani leniwe, ani chętne do załadowania, ale są bliższe chęci załadowania, z wyjątkiem tego, że pobierane są tylko kolumny z bazy danych, są naprawdę potrzebne do ViewModel, a nie do pełnej encji, która byłaby niepotrzebna narzut). Szczególnie ostatni fragment zapełnia również kolekcję 'Orders' (patrz wewnętrzna' Select'). W drodze powrotnej z ViewModel do encji korzystam z DTO, możesz ręcznie odwzorować właściwości z ViewModel na DTO lub użyć narzędzia takiego jak AutoMapper. – Slauma

Powiązane problemy