2012-06-05 43 views
9

我知道這個主題有很多帖子,但我找不到能幫助我做我想做的事情。我知道我最終會使用Automapper,但在我開始使用它之前,我想學習如何手動執行操作。我想要創建一個ViewModel,通過一個存儲庫來填充來自我的實體的值並將其發送給我的View。就像聽起來那麼簡單,我一直在努力完成它。我使用的是MVC 3,EF 4.3,Database First。我有自動生成我的課程。我張貼有關單位(簡稱/改名爲這個職位)和類,這裏是我到目前爲止有:我如何手動填充ViewModel(不使用AutoMapper!)

聚合實體:航運頭

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

} 

這裏是我的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; } 


} 

}

下面是一個查詢我回到我想用填充我的視圖模型與項目。我相信最好的地方是存儲庫。我驗證它返回我想要使用LinqPad的數據(因此缺少對我的dbContxt的引用)。我只是不知道如何從查詢中獲取值的視圖模型:

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

所以我不想使用Automapper做,再次,是與所有從ShippingHdr行來填充視圖模型實體並將其傳遞給我的視圖。

下面是需要映射的filelds:

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 

我困在這裏映射。 如何從查詢填充ViewModel? 那麼我怎麼從我的控制器調用這個動作呢?

我希望我已經提供了足夠的信息,任何幫助將不勝感激。

+0

提示,而不是'可空'你可以去''的DateTime您 –

+0

應該能夠說'選擇新ShippingHeaderSummaryVM {}? ',這是你輸出,而不是使用模型聯編程序輸入? –

+0

@Lavinski,我只是做了一個複製/粘貼的形式,我爲這篇文章生成的實體,我真的不明白爲什麼一些使用Nullable生成而其他人不是。我認爲它會匹配我的SQL表允許爲空,但它沒有。 –

回答

5

爲了填充基於您的視圖模型對象的出貨量,你需要創建一個映射方法,從您的從數據庫出貨量的集合映射到根據您的視圖模型的出貨量的集合的列表:

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; 

作爲一個側面說明,這成爲一個班輪你有AutoMapper後運行起來:

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

雖然,學習如何手工做的事情是偉大的。手動映射模型並不會以任何方式或形式真正讓您受益。使用AutoMapper。

+1

我打算使用Automapper,我只是覺得我需要首先真正理解機制。迫不及待想嘗試一下。謝謝 –

+0

當你說手動映射沒有提供任何好處時,我已經閱讀了一篇文章[link] http://www.devtrends.co.uk/blog/stop-using-automapper-in-your-data-access-代碼說,通過使用Automapper,在映射發生之前讀入整個模型。除了使用他構建的插件之外,這似乎是在出現性能問題時手動映射的潛在原因。我的應用程序的用戶正在使用基於衛星的互聯網服務,延遲是一個殺手,我希望儘可能減少數據庫訪問。 Automapper不會帶來比我需要的更多嗎? –

+0

自動映射器使用的「映射」本身通常在Global.asax方法的OnApplicationStarted部分中創建。在此配置中,您可以告訴automapper您想從域實體獲取哪些字段到視圖模型。根據我的經驗,automapper的性能與手動映射的性能沒有任何區別,我發現我的代碼更清晰,更易於遵循。國際海事組織將automapper帶來的好處稱爲非常非常微不足道(如果有的話)。你也可以單元測試你的映射! – Jesse

1

你也可以使用LINQ做這樣的事情......

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

請注意,當映射視圖模型是偉大的傳遞到一個視圖,總是做手工從視圖模型讀取更新時你的數據庫。

編輯:感謝您的錯字改正:-)

相關問題