2014-01-29 43 views
1

編寫從存儲庫中檢索數據的服務層方法的最佳實踐是什麼?服務應該有多少個GET方法?

比方說,我們有兩種型號:TeamUser(用戶是一個團隊的一部分):

public class User { 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int TeamId { get; set; } 
    public virtual Team Team { get; set; } 
    public bool Active { get; set; } 
} 

public class Team { 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public bool Active { get; set; } 
} 

如果我想寫的服務,通過各種條件的儲存庫檢索用戶數據,我必須編寫多種方法來獲取用戶,例如getAllgetAllByNamegetAllActiveByNamegetAllActiveByTeamIdgetAllActiveByNameAndTeamId等?

public IEnumerable<User> GetAll() 
{ 
    return _repository.GetAll(); 
} 

public IEnumerable<User> GetAllActiveByName(string name) 
{ 
    return _repository.GetBy(u => u.Name == name && u.Active); 
} 

public IEnumerable<User> GetAllActiveByNameAndTeamId(string name, int teamId) 
{ 
    return _repository.GetBy(u => u.Name == name && u.Active && u.TeamId == teamId); 
} 

這些只是簡單的例子,但在現實生活中,我們可以最終有幾十不同場景,服務方法時,模型比較複雜。

或者,也許這是最好有一個GetBy方法會返回基於所提供的過濾器的用戶?我使用的通用Repository模式和實施GetBy服務方法的時候,我可以用GetBy方法:

public IEnumerable<User> GetBy(Expression<Func<User, object>>filter) 
{ 
    return _usersRepository.GetBy(filter); 
} 

有了這個我就不用寫數萬「複製」的方法對所有的場景。 那麼這將是控制器的責任來設置過濾器:

public ViewResult Index(int teamId = 0){ 
    //[...] 
    var users = _usersService.GetBy(u => u.IsActive && u.teamId == teamId); 
    //[...] 
} 

上有什麼想法?

+0

擁有Google for「通用資源庫接口c#」。這讓你知道你需要什麼。 –

+0

@WimOmbelets我正在使用通用的存儲庫模式,我知道我需要在存儲庫中檢索數據。問題是關於檢索數據的SERVICE層方法。請閱讀其他評論。更新了問題以避免誤解。 –

回答

1

我認爲您應該擁有儘可能多的查詢方法。

以這種方式可以通過例如使用預先計算的視圖優化單個查詢。 你的一些查詢可能使用急切加載,其他可能使用延遲加載...

此外,如果你總是返回IQueryable你打算如何測試它?你的服務只有一個方法GetAll,這是非常貧窮的,你可以擺脫它,並直接在控制器中使用存儲庫。

GetAll另一種說法是,任何一個可以在UI執行任何查詢!

考慮閱讀關於CQRS。

+0

GetAll不會是服務中唯一的方法。還有其他處理業務邏輯的方法。我的帖子與檢索實體「列表」的方法有關。無論如何,我將擁有GetAll,所以我的問題是「我需要實現其他方法」,例如GetAllByThisAndThisAndThat,當我可以使用GetAll時,如果它已經存在。表現可能是編寫其他方法的一個很好的理由。 –

0

或者最好有一個getAll方法只返回 活動用戶,然後在控制器中使用lambda表達式?

不。這種查詢只適用於內存過大的靜態數據。假設你有一些應用程序級別的數據,並且它不會在一定時間內改變,那麼你不必每次都查詢它,你會第一次獲得所有數據,然後放入本地服務器緩存中。然後將其用於下一個同時請求。但是這種方法不適用於動態數據的大量變化。此查詢的性能取決於它返回的記錄數量,因此有時可能會導致性能很差。

我必須寫多個方法來獲取用戶如getAll, getAllByName,getAllActiveByName,getAllActiveByTeamId, getAllActiveByNameAndTeamId,etc?

這樣更好。這種方法將爲您提供按需自由加載,這意味着在需要時加載必要的數據,而不是獲取所有數據並丟棄它。