18

我正在开始一个新项目,并决定尝试合并 DDD 模式,还包括 Linq to Entities。当我查看 EF 的 ObjectContext 时,它似乎正在执行存储库和工作单元模式的功能:

从实体表示抽象出底层数据级接口的意义上的存储库,我可以通过 ObjectContext 请求和保存数据。

从某种意义上说,我可以将所有插入/更新写入 objectContext 并在执行 SaveChanges() 时一次性执行它们。

将这些模式的另一层放在 EF ObjectContext 之上似乎是多余的?似乎模型类也可以使用“部分类”直接合并到 EF 生成的实体之上。

我是 DDD 的新手,所以如果我在这里遗漏了什么,请告诉我。

4

3 回答 3

17

我不认为实体框架是存储库的一个很好的实现,因为:

  • 对象上下文不够抽象,无法对引用它的事物进行良好的单元测试,因为它绑定到数据库访问。相反,拥有 IRepository 引用更适合创建单元测试。
  • 当客户端可以访问 ObjectContext 时,客户端几乎可以做任何它关心的事情。您对此唯一真正的控制就是将某些类型或属性设为私有。这种方式很难实现良好的数据安全性。
  • 在一个重要的模型上,ObjectContext 不够抽象。例如,您可以将表和存储过程都映射到相同的实体类型。您真的不希望客户端必须区分这两个映射。
  • 与此相关的是,很难编写全面且执行良好的业务规则和实体代码。事实上,这是否是一个好主意是值得商榷的。

另一方面,一旦有了 ObjectContext,实现 Repository 模式就很简单了。事实上,对于不是特别复杂的情况,Repository 是 ObjectContext 和 Entity 类型的包装器。

于 2009-02-06T12:53:22.387 回答
7

我想说您应该将 ObjectContext 视为您的 UnitOfWork,而不是存储库。

ObjectContext 不能是存储库-imho-,因为它是“通用的”。您应该创建自己的存储库,在常规 CRUD 方法旁边有专门的方法(例如 GetCustomersWithGoldStatus)。

所以,我要做的是创建存储库(每个聚合根一个),并让这些存储库使用 ObjectContext。

于 2009-02-06T13:06:30.050 回答
0

我喜欢有一个存储库层,原因如下:

EF 的陷阱

当您查看当前有关 EF(Code First 版本)的一些教程时,很明显有许多问题需要处理,特别是围绕对象图(包含实体的实体)和断开连接的场景。我认为存储库层非常适合将它们包装在一个地方。

数据访问机制的清晰图景

存储库提供了关于 BL 如何访问和更新数据存储的特​​定图片。它公开了具有明确单一目的的方法,并且可以独立于 BL 进行测试。教科书中的标准示例Find()查找单个实体。一个更特定于应用程序的示例,Clear()用于清除数据库表。

优化的地方

使用 vanilla EF 时,您不可避免地会遇到性能问题。我使用存储库对 BL 隐藏优化机制。

例子,

GetKeys()从表中投影缓存的键(用于插入/更新决策)。仅读取密钥比读取完整实体更快并且使用更少的内存。

通过 SqlBulkCopy 批量加载。EF 将按单个 SQL 语句插入。如果您希望单个语句插入多行,SqlBulkCopy 是一个很好的机制。存储库对此进行封装并为 SqlBulkCopy 提供元数据。除了 Insert 方法,您还需要 StartBatch() 和 EndBatch() 方法,这也是 UnitOfWork 层的参数。

于 2012-12-13T11:53:26.007 回答