2017-02-23 118 views
1

我有以下的庫:庫設計混亂

  • EmployeeRepository
  • DocumentRepository
  • CourseRepository
  • LeaveRepository

我們有一個要求,現在增加一個新的業務對象調用BusinessTripBidding它允許員工出價不同的商務旅行等等。無論如何,問題是在返回Bidders列表時,我需要包含上述所有倉庫中的信息,然後生成一個新對象並返回一個列表(在我的業務對象中),如下所示:

IEnumerable<BidderInfo> GetBiddersInfo(int tripId) 
{ 
    List<Bidder> bidders = _bidderRepository.GetListByTripId(tripId); 

    List<Course> courses = _courseRepository 
     .GetListByEmployeeId(bidders.Select(b => b.EmployeeId).AsEnumerable()); 

    List<Document> passports = _documentRepository 
     .GetListByEmployeeId(bidders.Select(b => b.EmployeeId).AsEnumerable(), DocumentType.Passport); 

    List<Leave> leaves = ........... 

    var biddersInfo = new List<BidderInfo>(); 
    foreach(Bidder b in bidders) 
    { 
     var bi = new BidderInfo(); 
     bi.Courses = courses.Where(c => c.EmployeeId == b.EmployeeId).ToList(); 
     bi.Passport = passports.FirstOrDefault(p => p.EmployeeId == b.EmployeeId); 

     bi.ComingLeave = ......... 

     // the same for the rest of the repositories 

     biddersInfo.Add(bi); 
    } 
    return biddersInfo; 
} 

旁邊的多次調用DB和環旁,它會如果我建立新倉庫只負責打造這一個BidderInfo單一的查詢更加容易,讓我們把它BidderInfoGeneratorRepository然後在注入該庫業務對象的構造函數。

現在,我應該保留的東西,因爲我目前正在做(多個數據庫調用),但事情看起來是正確的; 或者我應該創建另一個存儲庫並將它傳遞給業務對象以使事情更快一點?這種情況下的最佳做法是什麼?

回答

1

最佳做法取決於數據量和數據更改速度。 如果您的數據只有幾百/幾千行並且變化緩慢,則可以將其緩存在應用程序中,並在更新時使緩存失效。 當您的數據太大而無法將其存儲在內存中時,我會盡可能避免多次調用,而不會大幅增加代碼複雜度。

+0

'沒有代碼complexity'這是問題的一個很大的增長..怎麼樣?我的方法是通過爲此創建一個新的存儲庫來糾正嗎? – Him

+0

在這種情況下,您可以創建一個新的存儲庫。 兩件小事:當我正確地看到它時,你正在過濾你的課程兩次。第二:我不會調用ToList()來設置bi.Courses,因爲它會降低性能。 – Dexion

+0

第一個過濾器是獲得的課程都被列入了這一要求所有的員工,GetByEmployeeId具有接受IEnumerable的''過載。第二個過濾器是獲取特定的員工。 – Him

1

我會避免倉庫之間的緊密耦合。

雖然我域第一數據不可知論和其他良好做法的大風扇,以實現基於DDD的架構,我會說,你仍然可以保留這些功能,而你並不需要夫妻你的資料庫就是這樣。

順便說一句,如果我理解正確的話你的方法,我發現有一個設計缺陷,在你的推理:BidderInfo域對象,但它不是一個持久化對象,不是嗎?存儲庫旨在與數據映射層一起工作,以保持域更改並提供不可知論查詢。

我讀到您的代碼的第一個結論是,整個方法應該進入域服務,您可以根據需要注入儘可能多的存儲庫,因爲它是正確的位置。

其次,有些東西可以更簡化事情,它可能是您的權威解決方案:爲什麼不將BidderInfo轉換爲可持久對象?

如果我認爲你使用的是OR/M,那麼我不應該猜錯,對嗎?因此,如果您以正確的方式配置它,您可以堅持BidderInfo並讓它自動填充到單個查詢中(或誰知道,但它將成爲OR/M優化角色)。因此,您將創建整個BidderInfoRepository,您只需執行一個GetById(...)即可在幕後調用OR/M。

否則,你應該把這個代碼放到服務層

+0

你的結論是正確的,這個想法就怎麼一回事,因爲有一個很好的性能增益,我認爲它甚至允許把一些邏輯在存儲過程中,如果這將使UA良好的性能增益..關於BidderInfo,這是一個對象不能直接保存在數據庫中,它會從其他許多表中獲取屬性,如圖所示。考慮爲報表之類的事情..糊塗這裏:) – Him

+0

@Him嘿;)閱讀[文章](https://martinfowler.com/bliki/CQRS.html)由Martin Fowler組成。讀完之後,我們可以繼續討論! –

+0

你讓我在過去的一個小時內瞭解了CQRS。這是一個非常酷的系統,但現在不可能重構一箇舊項目。謝謝你的提示,:) :) – Him