2011-06-22 3 views
0

チュートリアルの後、Steve Sandersonsのプロasp.netフレームワークブックです。私は、リポジトリパターンを使用して2つのデータベースオブジェクトの基本的な編集と表示機能を取得しました。viewmodelsまたはdomainオブジェクトを使用するときのMVC2の混乱

複数のオブジェクトからプロパティを表示/更新するときに問題が発生しています。

私はviewmodelsがこれを行う方法であるが、私はviewmodelをいつ使うべきか、それらが私のドメインモデルオブジェクトとどのように適合するべきかについて混乱していることを知っている。私は、リポジトリの、次のメソッドは、オブジェクトの各リストを返す必要が私の二つのオブジェクトのために例えば

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

} 
のようなビューをリポジトリからオブジェクトを渡して私のコントローライムで次に
public IQueryable<Customer> Customers 
    { 
     get { return customersTable; } 
    } 

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

私は2つのオブジェクトのプロパティを持つビューモデルを1つ持っているので、ビューモデルを使用して2つのオブジェクトのプロパティにアクセスできます。

{ 
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が最良の方法に参加していますか?ので、私はより多くの混乱場所です。ここで、顧客のコレクションを返すためにLINQクエリを含むメソッドが行くべき必要があり、これはリポジトリにあるべきか、

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

のように表示テンプレートから両方のオブジェクトにアクセスすることができますビューモデル?

答えて

0

私は、ドメインオブジェクトとビューモデルの2つの異なる責任を混乱させることを理解しています。

あなたのモデルはよく見えません。顧客は1つ以上のサイトを持っていますか?彼らの関係は何ですか?私の視点からは、リポジトリレベルで何ができるか、そのレベルでやってください。したがって、リポジトリレベルのデータを結合で集約し、データベースへの1回のラウンドトリップで返すことができるため、リポジトリから直接サイトを持つ顧客を返すことになります。

お客様の視点で複雑にする必要があることをご存知のように、2つの別個のエンティティCustomerとCustomerSiteを返すのはどうしてですか?あなたは、より多くの問題を作り出しています。

リポジトリから一度にCustomerとSiteを戻すと、たとえばCustomerWithSiteというフラットビューモデルオブジェクトにマップされた後になることがあります。そのためには、AutoMapper(http://automapper.codeplex.com/)を使用することができます。また、リポジトリ内のクエリと投影から発生するビュー用に整形されたオブジェクトを返すビュー用の "特別な"リポジトリを持つこともできます。それはあなた次第です。しかしビュー目的のためにあなたのドメインオブジェクトを使用しないでください。

また、私はリポジトリの外にIQueryableを公開しません。あなたは困ってしまうでしょう。なぜなら、いったん他のレイヤーがクエリを操作できるようにすると、リポジトリは返されるものについてはもはや責任を負いません。その後、一部のデベロッパーはビュー内でIqueryableを操作しようとしますが、欠点はデータベースに接続する必要があることです。私の視点からは、接続を開いたままにしておくことはあまり良いことではありません。以前に接続が切断された場合はどうなりますか?ビュー上にオブジェクトを表示しているときにDisposed例外が発生します。いいえ、いいえ。テスト容易性についても考えてください。

私はそれがあなたにとってより明確であるかどうかわかりませんが、私が話している欠点に注意してください。

+0

ありがとう、顧客は顧客サイトと1対多の関係を持っています。オートマッパーでは、各オブジェクトをビューモデル(顧客とサイトの両方)にマップする必要がありますか?または両方のオブジェクトのプロパティを結合してビューにマッピングする方法がありますか? – liam

+0

Automapperを使用すると、ほぼすべてをマップできます。同様の構造を持つオブジェクト、または必要に応じて2つのオブジェクトを1つのフラットオブジェクトにマッピングするための投影を行うことができます。それは設定です。しかし、ビュー・モデルで直接消費できる「特別な」ビュー・オブジェクトと戻ってくるリポジトリを作成する別の方法も考えてください。そのビューオブジェクトは、リポジトリ内のlinqクエリによって作成された投影(結合を使用して、これまでに何を望むか)を示したものです。 –

+0

あなたの助けをもう一度感謝し、物事を少しはっきりさせる助けになりました。私はリポジトリを使って特別なビューオブジェクトを作成してみました。 – liam

関連する問題