2013-01-09 63 views
7

將數據庫實體映射到模型並執行業務邏輯的最佳實踐是什麼?我已經看到了兩個不同的實現。我注意到了一些實現,其中Repository(在數據層中)本身負責將數據庫實體映射到域模型。例如,一個存儲庫這樣做:將實體映射到模型並在ASP.NET MVC中執行業務邏輯

public IQueryable<Person> GetPersons() 
{ 
     return DbSet.Select(s => new Person 
        { 
         Id = s.Id, 
         FirstName= s.FirstName, 
         Surname= s.Surname, 
         Location = s.Location, 
        }); 
} 

不過話說搜索全面周圍SO N個雙層設計,我注意到,雖然沒有銀彈,在大多數情況下,這是最好的內部執行映射MVC項目中的控制器手動或使用Mapper。還有人重申,服務層不應該執行映射,並且應該負責執行業務邏輯。這裏有幾個問題:

  1. 哪種方法對於將實體映射到模型以及反之亦然是可取的?存儲庫應該這樣做還是應該在控制器中完成映射?
  2. 假設我想對從數據庫中檢索到的實體執行一些業務邏輯,例如返回Person實體的全名,或者將所有Person的年齡增加10年,應該在何處操作被執行。在模型本身?例如,我會在模型上有一個FullName屬性來計算全名和年齡?還是我在我的服務層中定義一些服務來執行業務邏輯?

編輯

哇這麼多的接近票數。道歉,我沒有足夠全面的搜索。我在這裏提出的「在何處執行業務邏輯」的問題已經可以在SO和其他地方發現的(雖然有時有點傳達含糊):

Validating with a Service Layer by Stephen Walther

Skinny Controllers

Another great, but more generic answer here on SO

Where Should I put My Controller Business Logic in MVC

Does a Service Map Entities to a View Model

但是我還沒有找到標準的解決方案來解決映射問題,而且我想我可能更加雄辯地表達了我的問題。因此,普遍的共識似乎是業務邏輯進入服務層,並且將域模型映射到視圖模型應該發生在控制器/表示層中。由於不建議將數據庫實體映射到數據層以外的任何層,因此建議您將實體映射到數據層的域模型,可以手動或通過映射器(如Auto Mapper)進行映射(這是我從中收集的閱讀很多文章)。我的疑惑出現在將實體映射到域模型和映射域模型以查看模型的位置的問題。不過,正如我之前提到的,我可以更清楚地表達我的問題。造成混淆的原因是我已經閱讀過映射實體到域模型應該發生在控制器中,這應該改爲說:「將實體映射到域模型應該在稍後發生在數據上,並且映射域模型以查看模型應該發生在控制器中

回答

4
  1. 哪一種方法是在問候哪裏實體映射到 車型爲宜,反之亦然?存儲庫是否應該這樣做,或者應該在控制器中完成映射嗎?

我強烈希望看到映射發生在存儲庫而不是控制器。控制者需要像Suhas在他的回答中提到的那樣純粹作爲協調員。作爲替代方案,也許你可以利用在經過實體的存儲庫中的映射類,並返回一個映射模型 - 一種像Auto Mapper

  • 假設我要執行一些業務例如,我從 已從數據庫中檢索到的實體的邏輯,返回人名enity的全名 ,或將所有人的年齡增加10年, 應在何處執行此操作。在模型本身?對於 示例我將在模型上有一個FullName屬性,它將計算全名和年齡?或者我在服務層 內定義一些服務來執行業務邏輯?
  • 如果可能,請在服務上執行業務邏輯。爲什麼要將應用程序的負擔放在服務層應該做的事上?我相信這是服務的領域,而不是應用程序的。另外,我不認爲從模型返回串聯或派生的特性也是一件壞事。

    摘要:

    • 控制器從視圖處理請求,並將其轉發到 庫
    • 庫是管道到您的數據存儲
    • 服務從倉庫處理請求,處理業務邏輯, 並返回映射模型
    1

    我通常在MVC項目中創建一個小的服務層來處理MVC層需要完成的額外工作。因此,在您的示例中,您可以使用PersonServicePersonHandler調用業務層,以獲取所有人員實體,然後將所有人員的年齡增加10年(假設這不是業務邏輯,而只是UI需求),連接名字和姓氏以建立全名等等。然後控制器調用這個服務並且不知道幕後發生了什麼。通過這種方式,您的控制器正在做它理想的工作 - 在視圖和模型之間進行協調。

    1

    這取決於... 就像你說的那裏不是銀彈。人們只能列出每種方法的優點和缺點,但仍然是你比其他任何人更瞭解你的要求。 如果您有時間,建議您閱讀本書Patterns of Enterprise Application Architecture。這將使您很好地理解不同的業務邏輯和數據源架構模式,以及何時和如何使用它們。業務層應該發生什麼以及DAL應該發生什麼。 此書還解決了如何從DAL映射到域實體的問題。從長遠來看,你甚至可以改變你的想法並選擇完全不同的方法。

    還可以考慮使用一些ORM,它爲您提供了像EF First First或NHibernate這樣的Code First機制。在這種情況下,所有的映射邏輯對你來說都是透明的。

    1

    數據訪問層(存儲庫)應該只處理插入/更新/檢索您的數據實體。 您的服務層處理業務邏輯並負責您的表示層(控制器,視圖模型)和您的數據層之間的通信。這意味着你從數據實體到域的轉換應該發生在這一層。 您的表示層(控制器)應處理視圖模型和域模型之間的轉換。 - 如果您希望有更好的理解,您應該考慮Maksym的建議和選擇企業應用程序體系結構的模式(以及其他許多人)將Fowler視爲Web應用程序開發的權威。另一本好書是ASP.NET設計模式,它基於福勒的書,但只專注於ASP.NET框架。