1

C# と Razor で ASP.NET MVC3 を使用しています。アプリケーションのアーキテクチャは、データ アクセス レイヤー (EF クラス + リポジトリ)、サービス レイヤー、コントローラー、ビューモデル、ビューに分かれています。

2 つの EF クラスProducts(key ProdId) とProductCategories(key ProductCategoryId) があります。

これらは、 in class as external keyおよびin classで1対多の関係を介して関連付けられました。ProdCatIdProductsProductCategoryIdProductCategories

もちろん、 classから へのナビゲーション プロパティ もあります。hasCategoryProductsProductCategories

私はリポジトリクラスにメソッドを持っています:

 public IQueryable<Products> GetAllProducts()
 {
      return productDB.Products;
 }

ここで、対応するカテゴリのProductCategoryName(ではない) を含むすべての製品をビューに表示したいと考えています。ProdCatId私が使用するリポジトリでこの情報にアクセスするには (productDB は EF クラスです):

productDB.Products.Where(n => n.ProdId == prodId)
                  .Select(m => m.hasCategory.ProductCategoryName).First();

ビューでこの情報を取得するには、このコードをService Layerから使用するか、さらに悪いことにViewModelから使用する必要があります。ただし、この方法では、分離したいコンポーネント (サービス レイヤーと EF、または ViewModel と EF) 間の結合を作成します。

代わりに、この値をリポジトリ (メソッドstring GetProductCategory(int ProdId)) からサービス レイヤーに取得すると、 と一緒にGetAllProducts().ToList()2 つのオブジェクトが作成されます。

1) あList<Products>

2) あstring

これらの値を Controller に渡して ViewModel にラップするにはどうすればよいですか? ProductInfoこのデータをラップするクラスをサービス層に作成しますか? このソリューションは、 ControllerViewModel、およびクラスProductInfoの間の結合を作成します。

カップリングを作成しないために行うべき正しいことは何ですか?

4

2 に答える 2

1

Product と ProductCategory は、ビュー モデルではなくドメイン モデルです。Google ビューモデルとドメイン モデルを参照して、それらの違いをよりよく理解してください。

私があなたなら、ProductInfoViewModel というビュー モデルを作成します。このクラスには、製品について表示する情報のみが含まれます。

public class ProductInfoViewModel
{
   public string Name { get; set; }
   public string Category { get; set; }
}

これで、いくつかのデータを表示するために使用される単純なクラスができました。

はい、製品データを取得するためにリポジトリまたはサービス レイヤーを呼び出す必要があります。

var productDomainModel = productDB.Products.Where(n => n.ProdId == prodId)   
                  .Select(m => m.hasCategory.ProductCategoryName).First();   

ここで、productDomainModel をビューに渡す代わりに、製品ビュー モデルを作成できます。これは、表示したいプロパティのみを含むため、軽量になります。

var productViewModel = new ProductViewModel
{
   Name = productDomainModel .Name,
   Category = productDomainModel .Category
}

このビュー モデルをビューに渡すことができます。

return View(productViewModel);

ビューはビュー モデルを認識するようになりましたが、ドメイン モデルについては何も認識していません。これは良いことであり、関心の分離を促進します。

もう 1 つ、製品ドメイン モデルから製品ビュー モデルを作成するときに、Name = product.Name などの「ボイラープレート」コードを記述しました。

20 個のプロパティがあり、ドメイン モデルをビュー モデルに複数回マップしたい場合があるとします。これは非常に面倒な作業であり、Automapper などのツールをグーグル検索することで回避できます。

幸運を

于 2012-02-18T00:28:42.387 に答える
1

二つの考察。1)コードを次のように変更します

repository.GetAllProducts().Products.Where(n => n.ProdId == prodId)
              .Select(m => m.hasCategory.ProductCategoryName).First();

このように、コードは EF に依存せず、遅延実行を使用するだけです...つまり、Linq をサポートするすべてのもの (Linq2Sql、EF、NHibernate など) で動作します。

2) Product オブジェクトのプロパティ hasCategory をすぐに非表示にするだけで問題を解決することを検討してください。これは、怠惰な方法でそれらをロードしないことを意味します。これは、リポジトリまたはサービス層でセッションを管理するアプローチを使用する場合にのみ意味があります。ある種のリクエストごとのセッション アプローチを使用している場合、プロパティ (product.hasCategory.ProductCategoryName) は必要に応じて入力されます。

于 2012-02-17T10:38:14.403 に答える