实体框架,应用程序层和关注点分离

时间:2011-05-11 17:06:24

标签: entity-framework orm architecture entity-framework-4.1 separation-of-concerns

我正在为我的应用程序使用Entity Framework 4.1和ASP.Net MVC 3。 MVC提供了表示层,一个中间库提供了业务逻辑,实体框架类似于我猜的数据层吗?

我可以将实体框架代码分成一组存储库类,或者它的适当变体,无论构成一个有价值的数据层,但是我在解决我遇到的设计问题时遇到了问题。

如果存在多层方法来帮助我将问题分开,那么我选择的数据持久性也应该不是表示层的关注点。问题在于,通过使用实体框架,我基本上将我的应用程序紧密地耦合到实体更改被跟踪和自动持久化的概念。

因此,让我们假设在一个假设的世界中,我找到了不使用实体框架并希望将其交换掉的理由。一个设计良好的解决方案应该允许我在适当的层执行此操作并且不会影响依赖层,但是因为所有代码都是在数据层跟踪对象更改的情况下编写的,所以我只能交换实体以类似方式工作的框架,例如nHibernate。

如何使用实体框架,但不需要以假定数据层正在跟踪实体更改的方式编写代码?

对那些在自己的情景中仍然想知道这个问题的人进行更新:
Ayende Rahien写了一篇很棒的文章,打破了整个论点: http://ayende.com/blog/4567/the-false-myth-of-encapsulating-data-access-in-the-dal

4 个答案:

答案 0 :(得分:9)

如果你想继续这种方式,你应该放弃编程工作并开始学习哲学。实体框架是持久性的抽象,有一个Leaky abstraction规则,它表示任何非平凡的抽象在某种程度上都是漏洞。

敏捷方法带来了非常有趣的现象:不要为假设情况做好准备。大部分时间它只是Gold plating。每次更改都有其成本。在项目后期更改持久层是昂贵的,但也非常罕见。从客户的角度来看,没有理由在大多数不需要这种变化的项目中支付部分成本。如果我们更深入地讨论客户的观点,我们可以说他根本不应该为此付出代价,因为选择不好的API,以后必须更换的是开发人员/架构师的失败。定期重构您的代码,但仅限于添加客户想要的新功能所需的点,否则您将难以在市场上竞争。这当然有一些例外:

  • 客户希望(或架构以任何理由要求并且客户同意)这样的抽象。在这种情况下,您必须使用它并为这些更改定义开放架构。
  • 这是一个爱好或开源项目,你可以做你想做的事,因为它不受某些资源的限制

现在你的问题。如果您想要这样的高级抽象,则不应将实体暴露给控制器。从业务层(甚至从存储库)公开DTO,并向这些DTO添加IsNew,IsModified,IsDeleted等字段。现在您的UI与持久性完全分离,但您的体系结构要复杂得多,并且可能没有理由存在这种复杂性 - 它已经过度架构。另一种方法可以简单地关闭跟踪(向每个查询添加AsNoTracking())和在您的实体上创建代理(context.Configuration.ProxyCreationEnabled) - 延迟加载也不会起作用。这就像丢弃了持久性框架为您提供的大多数功能。

还有其他观点。我建议你阅读Ayende's最近有关存储库的帖子以及他对Sharp架构的评论。

答案 1 :(得分:2)

简短回答?你没有。你可以关闭EF的跟踪,然后不用担心它,但那就是它。

如果您打算编写表示层,期望自动跟踪和保留更改,那么无论您更换EF,都必须这样做。你无法将它换成不能自动跟踪和持续更改的东西,只是期望事情继续工作。这就像采用依赖TCP / IP连接进行双工通信的系统,将其交换为HTTP连接(由于HTTP本质上不是真正的双工)并期望事情以相同的方式工作。它没有。

如果您希望能够将持久层替换为其他内容而不必更改其他内容,则需要在自己的自定义代码中包装EF(或其他)以提供所需的功能。然后你必须提供任何你交换的东西都没有提供的实现。

这是可行的,但对于实际上很少发生的问题,这将是一项非常繁重的工作。它还将为项目增加额外的复杂性。拉迪斯拉夫说:“这远不值得抽象。”

答案 2 :(得分:0)

如果您担心可能会更换EF,您应该实现存储库模式和普通POCOS。

Codeplex上有一个很棒的项目,它涉及领域驱动设计,包括文档。看一看。

http://microsoftnlayerapp.codeplex.com/

答案 3 :(得分:0)

请在阅读Microsoft n层项目后阅读ayenede's weblog. Mr.ayende发布了有关微软n层项目优势和劣势的系列文章。