繁体   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