在组织方面,当我使用entity framework代码时,我应该在哪里进行常见的查询?
我正在使用EF 4.1 Code First从新的自制数据层迁移出一个新的数据层。
我已经build立了两个程序集,一个用于我的上下文,一个用于所有POCO代码的第一类。
我有一些业务逻辑,例如,针对在一些不同的地方使用的一个表(或几个表)的查询。 我应该把它放在哪里?
它不能进入POCO类,因为它join了一对表,所以需要一个上下文。 它可以放在上下文中,但是上下文会因为数百个混乱的查询而变得臃肿。 所有的业务逻辑是否有共同的模式或安排?
看来存储库模式是一切的解决scheme…存储库不是一个silverlight的子弹!
我每天都在使用EF模式,因为当我几个月前开始我的当前项目时,看起来就像推荐的解决scheme。 我的结论是:
- 版本库使得与EF的交互更加困难。 只需浏览与EF标签有关的问题,您就会看到必须直接在上下文,变更追踪器等上面处理哪些复杂性。
- 通用存储库适用于CRUD操作,但不适用于真正的DDDscheme。 一旦您的存储库与聚合根(DDD)通用方法失败。
- unit testing根本不起作用,因为一旦你公开了
IQueryable
,你将会嘲笑版本库和testing你的上层而不依赖于EF和数据库的一般思想。 Linq-to-entities只是Linq-to-objects的子集,而mock不能处理参照完整性,所以很多时候我看到了绿色的unit testing和运行时exception。 EF正确的testing方法是集成testing。 嘲笑仓库仅用于testing与数据访问无关的真实业务逻辑。 如果您没有针对访问或保留数据的业务方法进行集成testing,则不会对其进行testing。 - 公开像GetByXXX这样的专门方法只是退后一步。 大多数这些方法只使用一次。 您将以类似于用于包装存储过程调用的存储库的代码结束。 许多开发者喜欢ORM,只是因为他们可以避免这种僵化的架构。
EF本身已经提供了存储库模式 – DbSet
和ObjectSet
是存储库, DbContext
和ObjectContext
是工作单元。 所以在我看来,存储库模式被滥用。 在需要严格分层的大型项目中或者在其方法中添加其他逻辑的情况下,它可能非常有用。 仅仅因为你想包装对EF的访问而使用版本库通常是无价值的代码,只是额外的一层复杂性。
你可以用同样的方式创build可重用的方法来定义你的查询。
我会使用存储库模式。 下面是一个使用EF代码优先和MVC entity framework4 CTP 4 / CTP 5通用存储库模式和单元可testing的示例
这里有一些很好的模式:
- http://www.martinfowler.com/eaaCatalog/repository.html
- http://msdn.microsoft.com/en-us/library/ff649690.aspx
- http://www.devx.com/dotnet/Article/33695/0/page/5
因为你是从一个领域模型开始的,所以研究领域驱动devise(DDD)也是一个好主意。
一些好的DDD读数:
如果您直接在业务方法(域层服务和应用层服务)中使用EF,那么您并没有将域模型层与基础设施技术(在这种情况下是EF)隔离开来。 这是DDD原则之一。 你可能应该有一个每个聚合存储库。
有关DDD的更多信息,请参阅:
Eric Evans的书: http : //www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215
微软: http : //msdn.microsoft.com/es-es/architecture/en