2011-03-04 241 views
3

我們很喜歡EntityFramework(CTP5),並將其與ASP.NET MVC3一起使用。實體框架POCO +推薦模式

我不喜歡的是;事情混合在一起。

我可以在同一個班級,這意味着我MIXIN在數據庫驗證放置DisplayAttributeRequiredAttribute標籤RangeAttributeCompareAttribute在一起,一些業務邏輯UI產品總數。我甚至可以將ScriptIgnore屬性定製爲Json DTO對象。因此,我可以使用相同的POCO類來保留,演示,DTO和業務對象,並作爲我的domian模型。

您與EF POCO + MVC3工具集一起遵循哪些設計模式。你有什麼圖層? 你增加了什麼resposibilities到你的類(你的POCO類也是你的域模型)

回答

8

我使用視圖模型來解決這個問題。驗證和UI呈現屬性轉到視圖模型。在此模式中,控制器使用存儲庫獲取EF模型,將此EF模型映射到視圖模型(爲此,我使用AutoMapper),並將視圖模型傳遞給視圖。因爲視圖模型包含所有UI呈現屬性,所以視圖按預期行爲。每個視圖都必須有自己的視圖模型。這意味着您可以將多個視圖模型關聯到同一EF模型,但包含不同的屬性子集和基於視圖特定要求的顯示格式屬性。

該過程也可以以其他方式工作:控制器從視圖接收視圖模型作爲參數。它將視圖模型映射回模型並將EF模型傳遞到存儲庫。在視圖模型上處理UI驗證屬性是因爲您可以在不同的視圖中具有不同的驗證要求:例如插入/更新視圖。在插入視圖中,您將創建一個新實體,因此不需要Id屬性。在這種情況下,您甚至不會在視圖模型上擁有Id屬性。在更新視圖中相反,Id屬性將是必需的。

+0

您的控制器是否直接使用Repository,您是否有服務層來調用行爲? – hazimdikenli 2011-03-04 12:45:02

+0

@hazimdikenli,這將取決於我正在開展的項目。如果我有一個複雜的業務邏輯,我會使用服務層。如果沒有,並且CRUD存儲庫操作足以實現我想要的功能,那麼我可以直接在控制器中使用它們而不需要服務層。 – 2011-03-04 12:47:01

+0

即使在複雜的項目中,您也有簡單的任務,可能會導致使用服務層,從而增加額外的開銷,您將如何處理用戶通用服務,或者僅在具有業務邏輯的對象上使用服務。假設您正在使用服務發送訂單,但是您會使用服務來聲明新的UnitOfMeasurement嗎? – hazimdikenli 2011-03-04 12:55:56

3

我的POCO類幾乎都是域模型,幾乎從不查看模型,所以我沒有這些問題。

最佳做法是在從控制器傳遞數據到視圖(或作爲JsonResult)時使用特殊的「視圖模型」類。在這種情況下,您在該視圖模型中標記基於UI的屬性。在大多數情況下(除了純粹的粗糙應用程序),您需要顯示更多或更少的內容,因此您仍需要一些視圖模型(除非直接使用ViewData)。

只有當您想要使用它們進行業務/數據級別驗證時,域對象上的數據註釋纔有意義,這可以採用不同的規則,然後進行UI驗證。

如果您想遵循嚴格的DDD,其中POCO類是域對象=提供對象實例執行域邏輯的方法,您應該更進一步,因爲在這種情況下,您的業務應用不應將域對象暴露給控制器。在這種情況下,您最終會在商業門面上暴露數據傳輸對象並在控制器中使用。我不是純粹主義者,所以在這種情況下,我打算直接在DTO上使用數據註釋,但它取決於其他要求。

+0

你是什麼意思最後一段。 – hazimdikenli 2011-03-04 12:45:55

+0

我的意思是,如果你遵循DDD並且你創建了域對象,那麼它的方法只能用於商業/域邏輯層。如果你將這樣的對象暴露給控制器,你可以在表示層=>違反該規則的情況下調用它們。 – 2011-03-04 12:51:10

+0

感謝您的澄清,所以在這種情況下,您將如何檢查訂單是否可交付或可取消,並將其作爲屬性返回ViewModel? – hazimdikenli 2011-03-04 12:58:17