EF5中的UOW和Repository模式

4
这篇文章涉及到了我对实体框架资料的一些困惑: https://www.asp.net/ 在这个页面上,它解释了如何使用仓储库来封装dbcontext,并使用一个工作单元类来封装仓储库: http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application 然而,在这个页面上,它指出dbcontext已经是UOW模式和仓储库模式的结合体: https://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext(v=vs.103).aspx 所以,如果这些模式解决的问题已经被dbcontext解决了,为什么要在EF5中重新实现这些模式呢?
另外,在教程中,UnitOfWork类似乎没有展示出UOW应该具有的任何优点。例如,它陈述了:“这样,当工作单元完成时,您可以在上下文实例上调用SaveChanges方法,并确保所有相关更改将得到协调。” 但是,它似乎只是无谓地包装了dbcontext。我认为我漏掉了一些东西。我在这个实现中看不到任何协调...如果出现问题,如何进行“回滚”?

每次看到带有“工作单元”或“存储库”术语的问题与“entity-framework”标签结合时,我都会想同样的问题。我会关注这个... +1 - spender
@spender 是的,很有趣,有多少人试图在已经为他们抽象化数据库的东西上再添加另一个抽象层。我不认为这个问题中的OP很欣赏我的答案。我也将会关注这个问题。 - Alex
1
可能是重复问题 https://dev59.com/b2Yq5IYBdhLWcg3w5Um8 - qujck
4个回答

4

不要使用另一个UoW /存储库抽象层

正如OP所指出的那样,Entity Framework(类似于NHibernate和其他ORM)已经为您提供了数据库的抽象,包括事务性的“工作单元”和可用于您的“存储库”。

额外的UoW /存储库抽象层是一种反模式,应尽量避免。它们存在诸多问题,其中最重要的问题是:

  • 它们会阻止您使用底层ORM的全部功能(延迟加载、急切加载、复杂查询等)
  • 如果他们想提供除简单CRUD以外的任何附加好处,它们将是泄漏(即反映出底层ORM中存在的功能)。

但是......

我需要通过模拟我的存储库进行单元测试

不,你不需要。只需使用针对测试具体内容的数据库即可。如果希望速度更快,可以使用内存数据库(例如SQLite、Effort等)。

EF不强制执行未在数据关系中表达的业务逻辑......为了强制执行这种类型的逻辑,必须在EF上下文周围构建OUW /存储库/两者之一。

不,你不应该。将业务逻辑实现在基础设施抽象层(如工作单元或存储库)中是完全错误的。

  • 有价值的业务逻辑应放在领域实体、领域服务、领域命令或长时间运行的业务过程中。
  • 简单验证(即非null、值在xy之间)不需要:这些验证应在系统接口边界处解决。

另请注意,没有任何有价值的业务逻辑的简单CRUD样式操作不需要通过所有“层环”,即避免使用此模式:

  1. 数据库→没有行为的实体→DTO→视图模型→视图
  2. 编辑字段
  3. 视图→视图模型→DTO→没有行为的实体→数据库

只需在控制器中直接从ORM中以“视图模型”形状加载它,并直接保存它。

关于抽象

这些不必要的抽象和层环类似都是有害的。它们会使您的代码混淆、束缚您的手脚、泄漏、增加您的代码大小,因此增加代码中的错误数量,而不提供任何附加价值。

只有在它们为您提供了附加价值时才使用抽象,例如当您需要它们来解决横切关注点、捕获/管理体系结构中的重复模式等时......

仅为抽象而抽象是浪费时间。

在IT技术方面,我们需要创造有意义的抽象概念,以帮助我们更好地理解和处理问题。

2

我已经在这里详细讲述了,但是为了你的利益,我将进行总结。是的,Entity Framework 已经实现了 UoW (DbContext)和 repository(DbSet)模式。重复实现它们没有任何好处,事实上,这会大大增加项目的维护成本。

为什么Microsoft在入门教程中要包含此内容?老实说,我不确定,但这是一个错误,困扰着无数新的MVC开发者,甚至包括当我刚开始学习时。

某种程度上有一定的抽象可以带来好处,使你的项目不依赖于特定的数据获取方式。然而,这个抽象应该返回你的操作所需的特定数据,而不多也不少。出于缺乏更好的字眼,我称之为“服务”,尽管Microsoft通过SOA给那个词赋予了完全不同的含义。简单来说,就像你只是为你的应用程序创建一个API一样,就像你创建Web API一样,只是完全基于代码(不需要实际的HTTP连接)。然后,它就进入了你的DAL层(类库或类似物),你的项目可以引用它。


0
关于EF的问题在于它所暴露的OUW或Repository功能中没有业务逻辑。如果您调用SaveChanges,它将愉快地保存所有更改。然而,如果添加一个小部件需要添加一个Frobber,那么您就会遇到麻烦(除非有FK依赖)。对于任何未在数据关系中表达的业务逻辑,EF默认不强制执行。
要强制执行此类逻辑,您必须在EF上下文周围构建某种OUW/Repository/两者结合的东西。据我所知,这是唯一的原因。

-2

工作单元和仓储模式与实体框架无关,它是一种设计模式。因此,它用于使您的代码更易读、可重用和高效,同时这些模式也用于实现单例(一次对象实例化)以及避免控制反转。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接