c# - Entity Framework 与存储库模式

标签 c# entity-framework

我想知道存储库模式在使用 Entity Framework 的项目中是否有用。对此有相反的说法——有人说 EF 是存储库和工作单元模式本身的实现,因此不需要将它包装在下一个抽象层中,有人认为它具有 DAL 和 BL 分离和更容易创建等优点的单元测试。根据我的经验,我经常遇到以下方法(通常,不仅在 EF 项目中):

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(string login, string password) 方法。

在这种情况下,我们需要从数据库中获取整个用户实体,例如,它可以有 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 层的好处——单元测试实际上就是集成测试。因此,将其全部保存在 Controller 中并注入(inject)模拟的 DbContext 或使用类似 Effort 的东西进行单元测试可能会更简单(也更好)?

如果您能回答您如何看待这个问题以及您如何在您的项目中解决这个问题,我将不胜感激。

更新

我知道存储库模式允许轻松地将数据源/提供者更改为其他形式,如 nHibernate、LINQ-to-SQL、普通 ADO 等。

但是您能告诉我您是如何在存储库 API 中实现排序和分页的吗?我的意思是将排序和分页规范传递给存储库的最佳方式是什么?我看到一些 passes function predicates for LINQ 但这会将存储库与 LINQ 紧密耦合 - 将它与普通 ADO、存储过程等一起使用会出现问题。在我看来,创建许多像 GetUsersOrderedByNameDesc() 等方法是疯狂的。因此,也许为规范创建您自己的类,伪造和传递排序/分页标准,并在存储库中处理它?如果是,您能否提供一些实现示例?

最佳答案

我会尝试回答您的核心问题。这是我的两分钱。 为什么存储库与 Entity Framework 。在设计或选择哪个问题时,您需要回答我建议您提出的一些问题:

  1. 您的项目是否有可能与不同的存储库对话?如果是,那么基于 Entity Framework 的存储库模式就有意义了。
  2. 拥有存储库模式还可以让您更轻松地设置测试框架,您可以在其中拥有存储库模式 (DAL) 将使用的模型数据库。
  3. 您可能还需要考虑对数据模型的更改可以通过 Entity Framework 回溯到业务逻辑的更改。

关于c# - Entity Framework 与存储库模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24231791/

相关文章:

c# - 我们如何在 Entity Framework 中进行对象过滤?

c# - 如何枚举 C# 中的所有托管线程?

c# - In 和 Out 属性在 .NET 中如何工作?

java - 我有哪些选项可以读取 Excel 文件并评估 C#、Java 和 PHP 中的公式?

c# - EntityFramework 嵌套对象更新

c# - 什么是 EF 默认 ID 命名约定代码优先?

.net - Entity Framework 使用 LEFT OUTER JOINS 生成错误的 SQL

c# - 流利的断言 : Approximately compare a classes properties

c# - Windows 服务 : The underlying provider failed on Open 上的间歇性错误

c# - 获取给定 EntityType 的导航属性