2013-02-20 95 views
9

我有參與這個問題以下層:查詢Repository層中的多個實體時返回什麼類型?

  • 服務層(使用的IoC調用庫)
  • 域模型(POCO /域實體,定義儲存庫接口)
  • 庫層(EF。 EDMX並實施庫)

很多時候,它真的直截了當:庫層通過實體框架查詢數據庫,並返回IList<SomeDomainEntity>對來電者說這是服務層。返回的類型是在域模型中定義的類型。

我遇到的問題是當我需要跨POCOs A,B和C進行查詢並獲取所有要返回的數據時。由於我不處理存儲庫中的任何邏輯,因此我需要將此數據返回到要處理的服務層(直接或通過調用域模型上的某些邏輯來更可能)。但是,我沒有單一類型從存儲庫查詢的結果中返回給調用者。

在我看到的例子中,一個匿名類型的課程處理了這個問題,但由於我沒有直接在存儲庫中處理返回數據的邏輯,而需要返回它,所以我需要返回一個物理類型。這裏有一些解決方案,我想到了,但不知道我喜歡的:

  1. 創建域模型一個新的域實體,基本上是所有我查詢的數據的組合,所以這個新的單一類型都可以返回。這似乎是錯誤的創建abritrary類型來滿足查詢需求。
  2. 使服務層分別調用A,B,C實體上的各個存儲庫,然後處理來自每個返回對象的數據。這看起來像是很多額外的工作。
  3. 創建一個ViewModel返回。這對我來說似乎也不合適。我在我的服務層和UI層之間大量利用ViewModel類,但從未看到它們用於從存儲庫返回。

我不能是唯一一個跨多個實體查詢以獲得需要添加到類型並返回給調用者的數據集合的人。什麼是解決我的問題的常見做法或標準方法?

謝謝!

+1

我會選擇1.根據您的查詢創建視圖並將視圖映射到您的新域模型。 – Romoku 2013-02-20 17:28:56

回答

8

如果這些實體相關和您查詢他們都在一個地方,那麼你應該嘗試找到他們的aggregate root在您的域模型,或者如果它不存在,但你應該引入一個新的,如你在第一個選項中說。這是有道理的,直到它是有道理的。它應該模擬一個域的概念,你可能有一個,因爲你創建了這個存儲庫方法。

如果這些實體不相關(當然,在某些方面可能有關,但不是如上緊),你只想讓他們在一個去,那麼你應該處理,在服務層,在那裏你可以使用多個存儲庫並撰寫結果對象。

你可能聽說過的navigation propertieseager loading的概念,但我在這裏寫它,因爲它可能是另一種回答你的問題(我沒有看到你的域模型)

我不會跟你去第三建議(在存儲庫中創建視圖模型),因爲它會打破分色。

+1

感謝您的幫助,這可以清理很多東西。真正的小細節問題 - 你是否將聚合根實體分離到它們自己的文件夾中,並說'AggregateRootEntities'用於區別? – atconway 2013-02-20 21:14:46

+2

不,這種區別並不那麼尖銳,大多數時候他們都是頭等公民:)但這並不太重要,所以按照自己感覺舒適的方式組織起來。 – 2013-02-20 21:43:00

+0

因此,讓他們駐留在「DomainEntities」或「Entities」文件夾中也可以接受?意思是,我不必如此明確地將它們定義爲聚合根實體。 – atconway 2013-02-20 21:58:46

1

我建議你爲此使用DTO(數據傳輸對象)。將服務層與視圖分開是常見的做法,DTO允許您僅共享視圖所需的重要信息。

根據系統的大小,有多種方法可以實現這部分系統。在小系統中,您可以使用擴展方法將POCO實體映射到數據傳輸對象中

我建議您看看「AutoMapper」。我認爲這將是非常有用的,你

http://www.codeproject.com/Articles/61629/AutoMapper

http://lostechies.com/jimmybogard/2009/01/23/automapper-the-object-object-mapper/

+0

我實際上在我的體系結構的* upper *層中使用DTO和ViewModels,但是我的問題確實集中在* lower *層,包括存儲庫和域模型。 – atconway 2013-02-20 18:42:43

+0

我認爲你的存儲庫層只需要知道域實體。它是另一層(DDD中的應用程序層)的工作,用於映射和爲視圖準備此數據 – 2013-02-21 13:20:44

3

不同的實體可以涉及到對方內部消除其中一個是一個聚合根。服務用於這些查詢。我通常做這樣的事情:

public class MyService 
{ 
    IEnumerable<UserWithMessages> Find() 
    { 
     var messages = _messageRepository.FindAll(); 
     var userIds = _messages.Select(x => x.UserId).Distinct().ToArry(); 
     var users = _userRepository.Find(userIds); 
     return users.Select(x => new UserWithMessages(x, messages.Where(x => x.UserId == x.Id)); 
    } 
} 

這只是兩個DB查詢,可以利用數據庫中的索引。所以它應該很快。

+0

要將此示例映射到我的示例,我已經有了名爲'messages'和'users'的類。然而'UserWithMessages'是我必須創建的,並且像構成2個單獨類的某些元素的聚合根一樣行事,對嗎? – atconway 2013-02-21 17:47:58

+0

這是正確的 – jgauffin 2013-02-21 17:59:29