2011-02-23 111 views
1

考慮到以下Razor部分視圖並理解Product是NHibernate映射對象,所以此處對IEnumerable的調用將觸發數據庫查詢(未緩存時)。ASP.NET MVC 3:在視圖中使用枚舉擴展方法

這是不好的做法?我應該爲這個視圖提供一個更平坦的數據視圖,以便我可以在我的控制器/業務邏輯中進行這些調用?

@model IEnumerable<MyProject.Data.Models.Product> 
<table> 
    <tr> 
     <th></th> 
     <th>Total Orders</th> 
     <th>Fulfilled</th> 
     <th>Returned</th> 
     <th>In stock</th> 
    </tr> 
    @foreach (var product in Model) { 
     <tr> 
      <td> 
       @Html.ActionLink(product .Name, "Detail", "Product", new { id = product.Id }, null) 
      </td> 
      <td> 
       @product.Orders.Count 
      </td> 
      <td> 
       @product.Orders.Where(x=>x.Fulfilled).Count() 
      </td> 
      <td> 
       @product.Orders.Where(x=>x.Returned).Count() 
      </td> 
      <td> 
       @(product.Stock.Count - product.Orders.Count) 
      </td> 
     </tr> 
    } 
</table> 

回答

1

這是不好的做法嗎?

是的。。事實上,它打破了MVC模式 - 視圖不應該通過模型回調,只接受爲了完成它的唯一工作:呈現HTML。

如果您需要的不僅僅是一個實體的附加信息,請將您需要的所有信息填入ViewModel,然後將其傳遞給您的視圖。

另外,不要通過在模型中IEnumerable不循環,使用顯示模板:

@Html.DisplayForModel()

這樣做的好處是沒有明確的循環,以MVC公約的優勢,秉承在模型綁定時對模型進行建模。

+0

這似乎是一種簡單實用的做事方式,但我知道從M​​VC的角度來看它是錯誤的。 –

+0

是。每當你開始在視圖中編寫代碼時,除非是@Html。 ',警鐘應該熄滅,你應該重構你的視圖/控制器來簡化事情。將任何邏輯放入ViewModel或Controller中。 – RPM1984

+0

使用foreach循環訪問模型中的IEnumberable沒有什麼問題,只要它僅用於呈現HTML呈現邏輯即可。助手很棒,但不使用它們不會破壞MVC模式。 (@ product.Orders.Where(x => x.Fulfilled).Count()不過) –