簡體   English   中英

實體框架與存儲庫模式

[英]Entity Framework vs repository pattern

我想知道存儲庫模式在使用Entity Framework的項目中是否有用。 對此有相反的主張-有人說EF是存儲庫和工作單元模式本身的實現,因此無需將其包裝在下一個抽象層中,有人認為EF具有諸如DAL和BL分離以及易於創建的優點。單元測試。 以我的經驗,我經常遇到以下方法(通常,不僅在EF項目中):

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

Repository + Service + Type = Model

存儲庫具有僅負責數據訪問的方法,即:

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-實體和LINQ到對象)。

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

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

在這種情況下,我們需要從數據庫中獲取整個User實體,該實體可以具有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-to-SQL,純ADO等。

但是您能告訴我如何在存儲庫API中實現排序和分頁嗎? 我的意思是將排序和分頁規范傳遞到存儲庫的最佳方法是什么? 我看到一些用於LINQ的傳遞函數謂詞,但這將使存儲庫與LINQ緊密耦合-將其與普通ADO,存儲過程等一起使用會出現問題。 在我看來,創建諸如GetUsersOrderedByNameDesc()等的許多方法非常瘋狂。 因此,也許可以為規范創建自己的類,偽造並通過排序/分頁標准,然后在存儲庫中對其進行處理? 如果是,您能否提供一些實施示例?

我將嘗試嘗試您的核心問題。 這是我的兩分錢。 為什么選擇存儲庫還是實體框架。 在設計或選擇哪個問題時,您需要回答我建議您提出的一些問題:

  1. 您的項目是否有可能與之交談的不同存儲庫? 如果是,則實體框架上的存儲庫模式很有意義。
  2. 擁有存儲庫模式還可以使您更輕松地設置測試框架,在該庫中可以使用存儲庫模式(DAL)使用的模型數據庫。
  3. 您可能還需要考慮對數據模型的更改可以滲透到實體框架的業務邏輯更改中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM