在组织上,在使用实体框架代码优先时,我应该在哪里放置常见查询?

时间:2011-03-30 15:17:49

标签: .net entity-framework entity-framework-4.1

我正在使用EF 4.1 Code First布局一个新的数据层,从旧的自制数据层迁移。

我已经设置了两个程序集,一个用于我的上下文,一个用于所有POCO代码的第一个类。

我有一些业务逻辑,例如,针对在几个不同位置使用的一个表(或几个表)的查询。 我应该把它放在哪里?

它不能进入​​POCO类,因为它连接了几个表,因此需要一个上下文。它可能会进入上下文,但是上下文会因数百个无组织的查询而变得臃肿。 是否存在所有业务逻辑的共同模式或安排?

3 个答案:

答案 0 :(得分:73)

看起来存储库模式是所有内容的解决方案......存储库不是银弹!

我每天都在使用EF的存储库模式,因为几个月前我开始使用当前的项目时看起来像推荐的解决方案。我的结论:

  • 存储库与EF的交互更加困难。只需浏览与EF标签相关的问题,您就会看到必须直接在上下文,变更跟踪等方面处理哪些复杂问题。
  • 通用存储库适用于CRUD操作,但不适用于真正的DDD方案。一旦您的存储库使用聚合根(DDD),通用方法就会失败。
  • 单元测试完全不起作用,因为一旦您公开IQueryable,您将模拟存储库并测试上层而不依赖于EF和数据库的一般想法就会失败。 Linq-to-entities只是Linq-to-objects的子集,mock不能处理引用完整性,所以我看过很多次绿色单元测试和运行时异常。 EF的正确测试方法是集成测试。模拟存储库仅用于测试与数据访问无关的实际业务逻辑。如果您没有对访问或保留数据的业务方法进行集成测试,则表示您没有对其进行测试。
  • 公开像GetByXXX这样的专门方法只是退一步。大多数这些方法只使用一次。您将以与用于包装存储过程调用的存储库类似的代码结束。许多开发人员喜欢ORM只是因为他们可以避免这种严格的架构。

EF本身已经提供了存储库模式 - DbSetObjectSet是存储库,DbContextObjectContext是工作单元。因此在我看来,存储库模式被过度使用。它适用于需要严格分层的大型项目,或者在为其方法添加额外逻辑的情况下。仅仅因为想要封装对EF的访问而使用存储库通常是无价值的代码,而且只是额外的复杂层。

您可以以相同的方式创建定义查询的可重用方法。

答案 1 :(得分:4)

我会使用存储库模式。以下是首先使用EF代码和MVC Entity Framework 4 CTP 4 / CTP 5 Generic Repository Pattern and Unit Testable

的示例

以下是关于模式的一些好读物:

从开始使用域模型开始,研究域驱动设计(DDD)可能也是一个好主意。

关于DDD的一些好读物:

答案 2 :(得分:2)

如果您直接在业务方法(域层服务和应用层服务)中使用EF,那么您不会将域模型层与基础架构技术(本例中为EF)隔离开来。这是DDD原则之一。 你可能应该有一个每个聚合的存储库。

有关DDD的更多信息,请参阅:

埃里克埃文斯的书: http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215

微软: http://msdn.microsoft.com/es-es/architecture/en