实体框架也是持久层吗?

时间:2014-03-05 13:48:01

标签: entity-framework persistence layer 3-tier

行。我知道实体框架是ORM。我们使用它将数据从数据库映射到对象模型,从对象映射到关系数据。但它适用于持久层的背景?我们可以说持久层也是实体框架吗?

1 个答案:

答案 0 :(得分:1)

我会说 - 不!有很多关于这个主题的文章。但总的来说,您并不希望对象关系映射器具有数据持久性。实际上完全相反,保持持续无知,通过将数据类与不同类型的数据提供程序(如关系数据库,Web服务,XML文件等)一起使用,您可以从中受益。

为了保持数据持久性,您可以利用Repository patternUnit Of Work等不同的设计模式,这样您就可以真正将业务层与数据层分离。

Logical structure

好的,为了使自己清楚,因为通过评论非常困难,这里是对我想要解释的内容的更新。请记住,这只是我的解释,以及我使用EF的方式,我已经在不同的项目(桌面和网络)中使用它,但它不是通用的,但仍然涵盖很多最常见的场景。

因为我是Code First的忠实粉丝,我将从这个角度写下来。 Database Model是您的实体所在的位置。稍后基于这些实体,EF将生成您的数据库。那么在这个开发阶段重要的是什么 - 您希望对数据库进行规范化,并且希望正确设置所有导航属性。不是那么琐碎的任务,但它只是关心你的数据库的效率。

现在出现了一个棘手的时刻,你应该把数据提供给业务层,这是真的 - 只要我们只讨论使用存储库的数据库中的数据是非常有争议的。然而,即使这样,在数据和业务逻辑之间使用Repository时获得的一个好处是,在创建数据模型时,您不必考虑业务需求,之后即使在创建数据库模型时,您的前端究竟是什么样子,也不会使在业务层内部使用您的数据变得更加困难。

所以,在这一点上,让我们再次考虑一下您Database Model拥有这两个实体的示例案例CustomersOrders。当用户登录您的应用程序并想要查看他的订单时,您需要加入两个表,以便为前端提供所需的信息。选项1 - 您没有存储库,并且您直接从返回数据的方法使用DbContext。这意味着两件事 - 你必须在任何地方编写相同的代码来获取这些特定的信息和2 - 如果业务需求发生变化,并且在同一视图中,从现在开始用于向客户和他的订单显示必须显示一些额外的信息,让我们从第三个表中说出,然后会发生什么 - 你必须去你使用这个视图的每个地方并改变你检索数据的方式。选项2 - 您有存储库,您访问数据的所有方法都存储在那里,而Business Layer完全不知道它获取数据的方式,Database Model也对此无知商业模式的需求导致松耦合,只有一个地方你必须做出改变。在上面的场景中,如果您确实使用了Repository,并且在您的存储库中有一个名为GetUserOrders()的方法,并且在此方法中您可以进行数据库调用,连接等,以及Business layer所需的所有内容。以正确的方式获取数据是在需求发生变化时调用此方法,并且您还需要再包含一个表,这次您不必查找使用此数据的所有位置,只需必须修改一种方法,这就是全部。

在回来的路上几乎是一样的逻辑。如果您从前端返回了一些复杂数据,并且想要使用新数据保存/更新旧数据,那么您可以从业务层执行此操作,但这会导致与必须获取数据时相同的问题相反 - 你只需将复杂的数据传递给另一个知道如何处理它的Repository方法(比如可能有些数据应该直接保存到数据库中,而其他数据应该用于提供Web服务或者你想到的任何场景并且在这里 - 当某些事情发生变化时,比如 - 你想要使用更多的Web服务或相反的,你想要迁移到更多以数据库为中心的设计,你所要做的就是改变处理数据的方法是关注这种变化,仅此而已。

所以尽管我写这篇文章时我可以看到DbContext可以很好地充当存储库,在这方面也可以作为数据持久层,仍然有一些正当理由不让这发生了。特别是现在,当Web服务越来越受欢迎时,WebAPI2已经出局,并且经常使用RESTFull服务,我认为尽可能让EF持续无知是要走的路。

但是,这是我的意见。关于这个主题有很多文章,所以我建议你去谷歌阅读,因为我认为这是每个应用程序架构中非常重要的一部分。

P.S

回应您在编写我编辑的答案时写的评论: If I change data source I need to make changes in DAL anyway or in my example in repostitory. - 答案是肯定的。但是,如果不更改DAL,就无法更改数据源。问题是这样做有多容易。我认为,通过我已经写过的内容,你可以自己决定哪种方式更好,但仅仅因为我真的认为这是让EF持久无知的少数真正有力的论据之一。当您拥有Repository并且有一些方法需要处理数据操作时,每次与获取数据的方式相关的内容都会影响那些方法,而不会影响其他任何方法。如果您自由地使用上下文,在您的业务层中,即使稍微改变也可能会因为总是可能错过某些内容而给您带来很多麻烦,您必须完成整个代码以确保您已修复所有位置及其#39;只是没有在一个地方拥有所有的效率。