2011-06-22 80 views
0

遵循本教程是Steve Sandersons親asp.net框架書我已經設法使用存儲庫模式獲得兩個數據庫對象的基本編輯和顯示功能。MVC2混淆何時使用視圖模型或域對象

我有問題,當我想顯示/更新多個對象的屬性。

我知道viewmodels是一種方法來做到這一點,但我很困惑,當我應該使用viewmodel,以及他們如何適應我的領域模型對象。

例如,對於我的兩個對象,我有倉庫的以及下列方法的返回對象的每個列表

public IQueryable<Customer> Customers 
    { 
     get { return customersTable; } 
    } 

public IQueryable<CustomerSite> CustomerSites 
    { 
     get { return customerSitesTable; } 
    } 

然後在我傳遞的對象從倉庫到視圖像

public ViewResult List([DefaultValue(1)] int page) 
    { 
     var customerSitesToShow = customerSiteRepository.CustomerSites; 
     var customersToShow = customerRepository.Customers; 
     var viewModel = new CustomerSitesListViewModel 
     { 

      CustomerSites = customerSitesToShow.Skip((page - 1) * PageSize).Take(PageSize).ToList(), 
      customers = customersToShow.Skip((page - 1) * PageSize).Take(PageSize).ToList(), 

      PagingInfo = new PagingInfo 
      { 
       CurrentPage = page, 
       ItemsPerPage = PageSize, 
       TotalItems = customerSitesToShow.Count() 
      } 
     }; 

     return View(viewModel); //Passed to view as ViewData.Model (or simply model) 
    } 

} 
控制器IM

我現在明白我可以在一個視圖中使用視圖模型訪問兩個對象的屬性,所以我有一個視圖模型與我的兩個對象的屬性

{ 
public class SiteViewModel 
{ 
    public int Id { get; set; } 
    public int CustomerId { get; set; } 
    public string AddressLine1 { get; set; } 
} 

public class CustomerViewModel 
{ 
    public int Id { get; set; } 
    public string CustomerName { get; set; } 
    public string PrimaryContactName { get; set; } 
    public SiteViewModel Site { get; set; } 
} 

} 

然後當我運行此顯示模板被渲染,但我的客戶集合是空的,因爲我想我需要一個LINQ加入語句來檢索我強類型的顯示模板

public class CustomerSitesListViewModel 
{ 
    public IList<CustomerSite> CustomerSites { get; set; } 
    public PagingInfo PagingInfo { get; set; } 
    public IList<Customer> customers { get; set; } 
    public CustomerViewModel Customers { get; set; } 
} 

主視圖模型客戶名單和客戶網站? LINQ加入是否是最好的方式?這樣我就可以從顯示模板訪問這兩個對象,如

<%= Html.DisplayFor(x => x.Customers.CustomerName) %> 
<%= Html.DisplayFor(x => x.Customers.Site.AddressLine1) %> 

這是我得到更多的困惑,其中應包含LINQ查詢返回客戶收集應走的方法這應該是在倉庫或查看模型?

回答

0

根據我的理解,你混淆了領域對象和視圖模型之一的兩種不同職責。

我看不出你的模型。客戶是否擁有一個或多個網站?他們之間的關係是什麼?從我的角度來看,你可以做一個存儲庫級別,在這個級別上執行。所以我會直接從存儲庫返回一個Customer到它的Site,因爲您可以在存儲庫級別將數據與連接進行聚合,並將數據返回到數據庫。

爲什麼還要返回兩個單獨的實體Customer和CustomerSite,因爲您知道您需要將它們聚集在您的視圖中?你正在創造更多的問題,然後需要。

因此,可以在映射到平面視圖模型對象(例如稱爲CustomerWithSite)之後立即從存儲庫返回Customer和Site。爲此,您可以使用AutoMapper(http://automapper.codeplex.com/)。您也可以爲視圖創建一個「特殊」存儲庫,該視圖已經返回一個對象,該視圖是存儲庫中查詢和預測的問題。隨你便。但請勿使用您的域對象作爲視圖的用途。

我也不會在我的倉庫之外公開IQueryable。你會陷入麻煩。因爲有一次,您啓用其他圖層來操縱您的查詢,存儲庫不再負責返回的內容。然後一些開發人員會試圖在視圖中操作Iqueryable,但缺點是它需要連接到數據庫打開。從我的角度來看,不是很好的設計,以保持連接的開放。如果連接之前關閉了什麼?在視圖上顯示對象時,您會看到Disposed異常。沒有很好。也想想可測試性。

我不知道它是否對您更爲清楚,但請注意我所談論的缺點。

+0

謝謝,客戶與客戶網站有一對多的關係,使用自動映射器我必須將每個對象映射到客戶和網站的視圖模型?還是有辦法將兩個對象的屬性組合起來映射到視圖? – liam

+0

Automapper允許你映射幾乎所有東西。具有相似結構的對象或者您可以執行投影,以根據需要將兩個對象映射到一個平面對象。這是配置。但也要考慮另一種創建存儲庫的方法,該存儲庫可以直接在視圖模型中使用,並返回「特殊」視圖對象。那個視圖對象可以像我說的那樣通過你的linq查詢在倉庫中進行投影(使用連接和你想要的)。 –

+0

再次感謝您的幫助,它有助於讓事情變得更加清晰,即時查看使用存儲庫創建特殊的視圖對象,並將使用我的發現進行更新。 – liam