[英]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()等的許多方法非常瘋狂。 因此,也許可以為規范創建自己的類,偽造並通過排序/分頁標准,然后在存儲庫中對其進行處理? 如果是,您能否提供一些實施示例?
我將嘗試嘗試您的核心問題。 這是我的兩分錢。 為什么選擇存儲庫還是實體框架。 在設計或選擇哪個問題時,您需要回答我建議您提出的一些問題:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.