另外,在教程中,UnitOfWork类似乎没有展示出UOW应该具有的任何优点。例如,它陈述了:“这样,当工作单元完成时,您可以在上下文实例上调用SaveChanges方法,并确保所有相关更改将得到协调。” 但是,它似乎只是无谓地包装了dbcontext。我认为我漏掉了一些东西。我在这个实现中看不到任何协调...如果出现问题,如何进行“回滚”?
不要使用另一个UoW /存储库抽象层
正如OP所指出的那样,Entity Framework(类似于NHibernate和其他ORM)已经为您提供了数据库的抽象,包括事务性的“工作单元”和可用于您的“存储库”。
额外的UoW /存储库抽象层是一种反模式,应尽量避免。它们存在诸多问题,其中最重要的问题是:
但是......
我需要通过模拟我的存储库进行单元测试
不,你不需要。只需使用针对测试具体内容的数据库即可。如果希望速度更快,可以使用内存数据库(例如SQLite、Effort等)。
EF不强制执行未在数据关系中表达的业务逻辑......为了强制执行这种类型的逻辑,必须在EF上下文周围构建OUW /存储库/两者之一。
不,你不应该。将业务逻辑实现在基础设施抽象层(如工作单元或存储库)中是完全错误的。
null
、值在x
和y
之间)不需要:这些验证应在系统接口边界处解决。 另请注意,没有任何有价值的业务逻辑的简单CRUD样式操作不需要通过所有“层环”,即避免使用此模式:
只需在控制器中直接从ORM中以“视图模型”形状加载它,并直接保存它。
关于抽象
这些不必要的抽象和层环类似都是有害的。它们会使您的代码混淆、束缚您的手脚、泄漏、增加您的代码大小,因此增加代码中的错误数量,而不提供任何附加价值。
只有在它们为您提供了附加价值时才使用抽象,例如当您需要它们来解决横切关注点、捕获/管理体系结构中的重复模式等时......
仅为抽象而抽象是浪费时间。
在IT技术方面,我们需要创造有意义的抽象概念,以帮助我们更好地理解和处理问题。我已经在这里详细讲述了,但是为了你的利益,我将进行总结。是的,Entity Framework 已经实现了 UoW (DbContext
)和 repository(DbSet
)模式。重复实现它们没有任何好处,事实上,这会大大增加项目的维护成本。
为什么Microsoft在入门教程中要包含此内容?老实说,我不确定,但这是一个错误,困扰着无数新的MVC开发者,甚至包括当我刚开始学习时。
某种程度上有一定的抽象可以带来好处,使你的项目不依赖于特定的数据获取方式。然而,这个抽象应该返回你的操作所需的特定数据,而不多也不少。出于缺乏更好的字眼,我称之为“服务”,尽管Microsoft通过SOA给那个词赋予了完全不同的含义。简单来说,就像你只是为你的应用程序创建一个API一样,就像你创建Web API一样,只是完全基于代码(不需要实际的HTTP连接)。然后,它就进入了你的DAL层(类库或类似物),你的项目可以引用它。
工作单元和仓储模式与实体框架无关,它是一种设计模式。因此,它用于使您的代码更易读、可重用和高效,同时这些模式也用于实现单例(一次对象实例化)以及避免控制反转。