2009-01-05 49 views
8

我目前在玩Asp.Net mvc框架,並且喜歡它與經典的asp.net方式相比。我正在模擬的一件事是View是否可以接受導致(間接)訪問數據庫?ASP.Net Mvc - 視圖可以調用可能導致數據檢索的函數嗎?

例如,我使用控制器來填充一個自定義數據類,其中包含我認爲View需要完成其工作的所有信息,但是由於我將對象傳遞給視圖,因此它也會導致數據庫讀取。

一個快速的僞示例。

public interface IProduct 
{ 
    /* Some Members */ 

    /* Some Methods */ 
    decimal GetDiscount(); 
} 

public class Product : IProduct 
{ 
    public decimal GetDiscount(){ ... /* causes database access */ } 
} 

如果視圖訪問產品類(它被傳遞一個IProduct對象),它可以調用GetDiscount()而引起的數據庫訪問。

我在想辦法來防止這種情況。目前我只爲Product類提供多種接口繼承。現在不用實施IProduct,而是實施IProduct和。 IProductView將列出類的成員,IProduct將包含可能導致數據庫訪問的方法調用。

「查看」將只瞭解接口到類,並不能稱之爲造成數據訪問方法。

我對「鎖定」它被傳遞到前視圖的對象等模糊的想法,但我可以預見的副作用這樣的方法巨大範圍。

所以,我的問題:

  • 是否有關於這個問題的最佳做法?
  • 使用MVC的其他人如何阻止視圖變得淘氣並且對對象做的事情比他們應該做的更多?

回答

3

您的看法並非真正導致數據訪問。該視圖只是在模型接口中調用GetDiscount()方法。這是導致數據訪問的型號。事實上,您可以創建另一個不會導致數據訪問的IProduct實現,但不會改變視圖。

模型對象做遲緩裝載必然導致數據訪問時的視圖嘗試爲顯示提取數據。

是否可以迴歸個人品味和偏好。

但是,除非您有充分的延遲加載原因,否則我寧願將數據加載到模型對象中,然後將該「已準備好的」數據傳遞給要顯示的視圖。

+0

我想向視圖提供已準備好的烘焙數據,那就是我在控制器中所做的事情(我使用構建器創建視圖模型類),我(可能過早地)想要迎合將來可能需要的情境在交易中的所有數據庫訪問 - 例如 - 在視圖中不容易控制! – Ash 2009-01-06 00:25:59

1

我正在調用的一件事是View是否可以接受導致(間接)訪問數據庫?

我經常問同樣的問題。我們在堆棧溢出視圖中的模型上訪問的許多內容可能會導致隱式數據庫訪問。這幾乎是不可避免的。很想聽到別人對此的看法。

+1

MVC中的模型不是強大的領域模型。或者至少它不應該。這是一個輕量級的視圖模型 - 一個零級安全的扁平DTO和其他表示對象的層次結構。您的控制器和其他服務構建視圖模型;該視圖簡單地呈現它。 – 2009-01-07 12:28:26

0

模型不應該有一個包括數據訪問方法(「行動」)。這是DAL的擔憂。 YOu可以有一個存儲在產品類中的折扣百分比屬性,並使GetDiscount方法返回一個簡單的計算,如Price *(100 - discountPercent)或類似的東西。

我從數據訪問斷開我的業務實體(在你的榜樣產品)。這是存儲庫(在我的情況下)的關注。

+0

我的模型中有一些方法可以防止出現這種情況,即在允許任何其他代碼觸摸它之前,您只需要「填充」對象就可以不必要地執行昂貴的數據庫操作。如果在這種特殊情況下,你從不使用折扣價值,但仍然可以檢索它? – Ash 2009-01-06 00:18:50

+0

我也許應該補充一點,GetDiscount()可能是方法名稱的錯誤選擇,也許GetCategories()可能更適合。即與類所代表的對象直接相關的東西,但實際上並不是數據庫表的一部分。 – Ash 2009-01-06 00:20:03

+0

@Ash:對於GetCategories()示例,我將使用MenuDocument對象填充我的ViewData,該對象包含呈現類別菜單所需的所有信息。 MenuDocument本身可以由ActiveRecord風格的域類填充。 – 2009-01-06 00:22:26

1

如果你讓你的域對象「持續不知情」,那麼你就沒有這個問題。也就是說,爲什麼不只是有一個名爲Discount的簡單屬性,而不是在Product類中有getDiscount?這會在從數據庫加載Product類的實例時由ORM設置。

0

我在MonoRail中建立了一個站點,在那之前有時候會有方法從視圖中觸發數據訪問。我儘量避免它,因爲當它失敗時,它可能以非常規和不可修復的方式失敗(例如,我不能真正嘗試/捕獲NVelocity模板)。這完全不是世界的盡頭 - 我寫了很多年抽象的PHP站點,從視圖訪問數據庫,他們仍然工作得很好,因爲大部分時間,如果事情發生了,你只是重定向到一個「無論如何,什麼都不起作用「 - 類型錯誤頁面。

但是,我儘量避免它。從更廣泛的意義上說,我的領域模型通常不會一直流入視圖。相反,該視圖呈現Document對象,這些對象只是強類型的數據轉儲,所有的預格式化,鞭打,壓縮和純化到視圖只需要用某些循環吐出一些字符串的位置,並且if/else,將數字「4」轉換爲4星形圖像等等。該文檔通常由位於漂亮域模型前面的Web服務返回,或者它只是一個簡單的結構,它在控制器中構建並傳遞作爲ViewData的一部分。如果直接使用域對象,那麼通常不會明確觸發數據訪問;這是由視圖無權訪問且域對象通常無權訪問的集合式存儲庫處理的。

但是你不必這樣做。你可能只是足夠受歡迎,而不是從視圖中調用那些觸及數據庫的方法。

相關問題