2012-03-27 5 views
7

Ich habe EF 4 im Projekt implementiert. Darin befinden sich Tabellen Kunden und Bestellung. Welche Beziehung hat (Kunde) zu vielen (Bestellung).Wie Design ViewModel

Ich erstelle ein Viewmodel für beide (CustomerViewModel und OrderViewModel) von meiner Domänenebene an Schnittstellenebene (MVC in diesem Fall) übergeben werden.

Nun ist die Frage „muss ich beide Ansichtsmodell verweisen? Zum Beispiel in customerviewmodel IEnumerable<OrderViewModel> hat und in orderviewmodel hat CustomerViewModel. Wenn ja, wie ich sie entwerfen (als Best Practice), so dass IEnumerable<OrderViewModel> und CustomerViewModel mit bevölkert die richtige Referenz?

+0

Sehen Sie, ob dies hilft: http://blogs.teamb.com/craigstuntz/2009/12/31/38500/ –

+0

Entschuldigung nicht relevant .. – user384080

Antwort

23

Ich würde immer das Design von ViewModels mit der spezifischen Sicht, nie aus der Sicht des Domänenmodells (= die Entitäten) fahren.Wie ein ViewModel aussieht hängt davon ab, was Sie anzeigen möchten und was Sie möchten in einer Ansicht ändern

Als Ergebnis haben Sie nicht die OrderViewModel und THE CustomerViewModel, weil Sie verschiedene Ansichten haben, die eine Bestellung oder einen Kunden oder Teile davon anzeigen oder bearbeiten. Also, Sie haben diese ViewModels für einen bestimmten Zweck und Ansicht und daher mehrmals in verschiedenen Variationen.

Angenommen, Sie haben eine OrderEditView und diese Ansicht ermöglicht es, Bestellinformationen zu bearbeiten und den Kunden dieser Bestellung anzuzeigen. Sie würden eine OrderEditViewModel wie dieses:

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

Diese OrderEditCustomerViewModel braucht keinen Hinweis auf die OrderEditViewModel.

Sie können dieses Ansichtsmodell bevölkern etwa so:

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

Auf der anderen Seite, wenn Sie ein CustomerEditView haben, die Bearbeitung Kundeninformationen ermöglicht und zeigt die Aufträge des Kunden in einer Liste, könnte das Ansichtsmodell sein:

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

Hier CustomerEditOrderViewModel braucht keinen Hinweis auf die CustomerEditViewModel und Sie können das Ansichtsmodell aus der Datenbank auf diese Weise zum Beispiel erstellen:

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

Die Customer(*)ViewModel s und die Order(*)ViewModel s sind anders - in Bezug auf die notwendigen Referenzen, die Eigenschaften und die Daten Anmerkungen je nach Ansicht, in der sie verwendet werden.

Mit diesen Überlegungen verschwindet die Frage nach gegenseitigen korrekten Referenzen zwischen OrderViewModel und CustomerViewModel verschwindet, weil Sie normalerweise eine solche bidirektionale Referenz für Ihre Ansichten nicht benötigen.

+0

Slauma .. Wie machen Sie das Mapping zwischen Viewmodel auf die EF-Entität und umgekehrt? – user384080

+0

auch .. Wie füllen Sie öffentliche IEnumerable Orders {erhalten; einstellen; } im CustomerEditViewModel? machst du faul oder begierig? – user384080

+0

@ user384080: Das Mapping von der EF-Entity zu ViewModel sind die beiden Code-Snippets mit dem 'Select' (es heißt" projection "und weder lazy noch eager loading, sondern eher eager loading mit dem Unterschied, dass nur die Spalten aus der DB abgerufen werden werden wirklich für das ViewModel benötigt, nicht die vollständige Entität, die unnötiger Overhead wäre). Besonders das letzte Snippet füllt auch die 'Orders'-Sammlung (siehe das innere' Select'). Für den Rückweg von ViewModel zu Entity verwende ich DTOs, Sie können die Eigenschaften von ViewModel manuell DTO zuweisen oder ein Tool wie AutoMapper verwenden. – Slauma