2012-06-05 7 views
9

Ich weiß, dass es viele Beiträge zu diesem Thema gibt, aber ich kann keine finden, die mir helfen zu tun, was ich will. Ich weiß, dass ich irgendwann Automapper benutzen werde, aber bevor ich anfange damit zu spielen, möchte ich lernen, wie man Dinge manuell macht. Ich möchte ein ViewModel erstellen, es mit Werten aus meinen Entitäten über ein Repository füllen und es an meine View senden. So einfach sich das anhört, ich buggle, um es zu schaffen. Ich benutze MVC 3, EF 4.3, Datenbank zuerst. Ich habe meine Kurse automatisch generiert. Ich bin die zuständigen Stellen veröffentlichen (abgekürzt/für diesen Beitrag umbenannt) und Klassen, hier ist das, was ich bisher:Wie bearbeite ich ViewModel manuell (ohne AutoMapper!)

Aggregate Entity: Versand-Header

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

} 

Hier ist mein Viewmodel

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


} 

}

Hier ist eine Abfrage ich habe die Einzelteile zurückbringen ich mit meinem Ansichtsmodell verwenden möchten, füllen. Ich glaube, der beste Platz dafür ist in einem Repository. Ich habe überprüft, dass es die Daten zurückgibt, die ich mit LinqPad verwenden möchte (daher die fehlende Referenz zu meinem dbContxt). Ich weiß nur nicht, wie die Werte aus der Abfrage an das Ansichtsmodell erhalten:

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

Also, was ich tun will, wieder ohne AutoMapper zu verwenden, ist das Ansichtsmodell mit allen Zeilen aus dem ShippingHdr aufzuzufüllen Entität und übergeben Sie es meiner Sicht.

Hier sind die filelds, die zugeordnet werden müssen:

ShippingHeaderSummaryVM von Sendungen

abgebildet
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 

ich hier stecke. Wie befülle ich das ViewModel aus der Abfrage? Wie rufe ich dann diese Aktion von meinem Controller?

Ich hoffe, ich habe genug Informationen gegeben, jede Hilfe wäre willkommen.

+0

Tip, statt 'Nullable ' Sie können einfach gehen '' Datetime –

+0

Sie sollten 'wählen neue ShippingHeaderSummaryVM sagen können {}? ', das wird ausgegeben, anstatt den Modellbinder für die Eingabe zu verwenden? –

+0

@Lavinski, ich habe gerade eine Kopie/Paste-Form meiner generierten Entitäten für diesen Beitrag erstellt, ich verstehe nicht wirklich, warum einige mit Nullable generiert wurden, während andere nicht waren. Ich dachte, es würde passen mit meinen SQL-Tabellen erlauben Null, aber es nicht. –

Antwort

5

Um eine Liste der Sendungen auf Ihrem Ansicht Modellobjekt basierend auf bevölkern Sie benötigen würden ein Mapping-Verfahren erstellen aus Ihrer Sammlung von Sendungen aus Ihrer Datenbank eine Sammlung von Sendungen auf der Grundlage Ihrer Ansicht Modell zur Karte:

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; 

Als Randbemerkung, wird dies ein Einzeiler, nachdem Sie AutoMapper und läuft haben:

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

Während das Lernen, wie die Dinge zu tun, ist von Hand groß. Das manuelle Zuordnen von Modellen kommt Ihnen in keiner Weise zugute. Geh mit AutoMapper.

+1

Ich beabsichtige, mit Automapper zu gehen, ich habe nur das Gefühl, dass ich zuerst die Mechanik wirklich verstehen muss. Ich kann es kaum erwarten, das auszuprobieren. danke –

+0

Wenn Sie sagen, dass die manuelle Zuordnung keinen Vorteil bietet, habe ich einen Artikel gelesen [link] http://www.devtrends.co.uk/blog/stop-using-automapper-in-your-data-access- Code, der besagt, dass mit Automapper das gesamte Modell vor dem Mapping eingelesen wird. Abgesehen von der Verwendung des Plugins, das er erstellt hat, scheint dies ein möglicher Grund für die manuelle Zuordnung zu sein, wenn es ein Leistungsproblem gibt. Die Benutzer meiner App verwenden satellitengestützten Internetdienst und die Latenz ist ein Mörder. Ich versuche, den Datenbankzugriff so weit wie möglich zu reduzieren. Würde Automapper nicht mehr bringen, als ich brauche? –

+0

Die "Mappings" selbst, die automatisch verwendet werden, werden im Allgemeinen im Abschnitt OnApplicationStarted der Global.asax-Methode erstellt. In dieser Konfiguration können Sie automapper mitteilen, welche Felder Sie von Ihrer Domain-Entität in Ihr View-Modell übernehmen möchten. Aus meiner Erfahrung unterscheidet sich die Leistung von automapper nicht von der eines manuellen Mappings und ich finde, dass mein Code sauberer und leichter zu folgen ist. IMO die Vorteile, die automapper auf den Tisch bringt, wiegen einen sehr, sehr vernachlässigbaren Treffer (wenn überhaupt). Sie können Ihre Abbildungen auch einzeln testen! – Jesse

1

Sie können auch Linq verwenden, so etwas zu tun ...

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

Beachten Sie, dass während Mapping Ansicht Modelle groß ist für auf eine Ansicht vorbei, immer manuell tun es, wenn aus einem View-Modell Lesen zu aktualisieren Ihre Datenbank.

Edit: Danke für die Tippfehlerkorrektur :-)

Verwandte Themen