2014-06-15 203 views
2

我想知道使用實體框架的項目中存儲庫模式的用處。對此有相反的說法 - 有人說EF是存儲庫和工作單元模式本身的實現,所以不需要將其包裝在下一個抽象層中,有人認爲它具有諸如DAL和BL分離以及更容易創建等優點的單元測試。根據我的經驗,我經常遇到以下的方法(一般,不僅在EF項目):實體框架vs存儲庫模式

Repository (DAL) <-> Service (BL) <-> Controller 

Repository + Service + Type = Model 

Repository有隻負責數據訪問,即方法:

public interface IUsersRepository 
{ 
    IEnumerable<User> GetAll(); 
    User Get(int id); 
    User GetByLogin(string login); 
    void Update(User item); 
    void Delete(int id); 
    void Delete(User item); 
    // ... 
} 

通常情況下,有使用通用存儲庫來代替,該方法接收功能過濾,排序等

反過來服務使用信息庫,並且包含業務邏輯,即:

public interface IUsersService 
{ 
    // ... 
    bool VerifyPassword(string login, string password); 
    void ChangePassword(string login, string password); 
    // ... 
} 

據我瞭解,服務應該不會有什麼DAL操作 - 這意味着我們不應該從即返回倉庫IQueryable的集合,因爲這樣的查詢將外庫和單元測試執行不會是完全可靠的(之間的差異LINQ-to-Entities和LINQ-to-Objects)。

我在這裏看到了查詢效率的問題 - 我們通常會從數據庫中獲取比需要更多的數據,然後將其過濾到內存中。

例如,讓我們考慮bool VerifyPassword(字符串登錄,字符串密碼)方法。

在這種情況下,我們需要從數據庫中獲取整個用戶實體,例如,可以有50個屬性,僅用於密碼驗證目的。我們當然可以,創建庫許多方法,如:

string GetPasswordHash(string login) 

bool VerifyPassword(string login, string passwordHash) 
{ 
    return db.Users.Any(x => x.Login = login && x.Password = passwordHash); 
} 

,而不需要從數據庫中獲取完整的實體,但在我看來,這可能是一個「小」的開銷。

我們也可以將VerifyPassword函數從服務移動到存儲庫 - 那麼我們應該問自己一個問題,是否需要兩個層 - 存儲庫和服務。但是如果我們合併它們,我們將失去分離DAL和BL層的益處 - 單元測試將是現實中的集成測試。所以也許它會更簡單(更好)將它全部保存在控制器中,並注入模擬的DbContext或使用像Effort這樣的單元測試?

我將非常感謝您的回答,您如何看待這一情況以及如何在您的項目中解決此問題。

UPDATE

我明白,存儲庫模式允許容易地改變像的nHibernate數據源/提供者以外,LINQ到SQL,平原ADO等。

但是你能告訴我你如何在你的倉庫API中實現排序和分頁嗎?我的意思是將排序和分頁規範傳遞給存儲庫的最佳方式是什麼?我看到有些函數爲LINQ函數使用了謂詞,但是這會將存儲庫與LINQ緊密結合 - 使用它與純ADO,存儲過程等將會產生問題。創建像GetUsersOrderedByNameDesc()等許多方法在我看來是瘋狂的。所以也許創建自己的規範類,僞造和傳遞排序/分頁標準,並在庫中處理它?如果是的話,你能給我提供一些實現的例子嗎?

+1

我不確定實際問題是什麼,所以這是一個評論,而不是讓你更具體的答案。當然,這是一個不錯的主意,它擁有存儲庫層和單獨的服務層。提到的VerifyPassword是一個很好的服務方法的候選者,它只會在存儲庫語言而不是DAL語言中實現。 –

+0

我不同意,但沒關係。它只是表明這個問題對於StackOverflow的Q&A格式來說太廣泛了。 –

回答

0

我會嘗試去嘗試你的核心問題。這是我的兩分錢。 爲什麼存儲庫vs實體框架。您將需要回答下面的一些問題,我建議您在設計或選擇哪一個時問:

  1. 您的項目是否有可能有不同的存儲庫?如果是,那麼存儲庫模式通過實體框架是有意義的。
  2. 擁有存儲庫模式還可以讓您更容易地設置您的測試框架,您可以在存儲庫模式(DAL)將使用的模型數據庫中進行設置。
  3. 您可能還想考慮對您的數據模型所做的更改可能會滲透到您的業務邏輯與實體框架的更改。