我正在使用EF 4.1 Code First布局一个新的数据层,从旧的自制数据层迁移。
我已经设置了两个程序集,一个用于我的上下文,一个用于所有POCO代码的第一个类。
我有一些业务逻辑,例如,针对在几个不同位置使用的一个表(或几个表)的查询。 我应该把它放在哪里?
它不能进入POCO类,因为它连接了几个表,因此需要一个上下文。它可能会进入上下文,但是上下文会因数百个无组织的查询而变得臃肿。 是否存在所有业务逻辑的共同模式或安排?
答案 0 :(得分:73)
看起来存储库模式是所有内容的解决方案......存储库不是银弹!
我每天都在使用EF的存储库模式,因为几个月前我开始使用当前的项目时看起来像推荐的解决方案。我的结论:
IQueryable
,您将模拟存储库并测试上层而不依赖于EF和数据库的一般想法就会失败。 Linq-to-entities只是Linq-to-objects的子集,mock不能处理引用完整性,所以我看过很多次绿色单元测试和运行时异常。 EF的正确测试方法是集成测试。模拟存储库仅用于测试与数据访问无关的实际业务逻辑。如果您没有对访问或保留数据的业务方法进行集成测试,则表示您没有对其进行测试。 EF本身已经提供了存储库模式 - DbSet
和ObjectSet
是存储库,DbContext
和ObjectContext
是工作单元。因此在我看来,存储库模式被过度使用。它适用于需要严格分层的大型项目,或者在为其方法添加额外逻辑的情况下。仅仅因为想要封装对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