EF5中的UOW和存储库模式
这是关于我从这里找到的一些entity framework材料的一些混淆: https : //www.asp.net/
在本页中,它解释了如何使用存储库包装dbcontext并使用工作类单元包装存储库: http : //www.asp.net/mvc/overview/older-versions/getting-started-with-ef使用-5–MVC-4 /实施最库和-单元的功图案-在-AN-ASP-净-MVC的应用程序
但是,在此页面上,它指出dbcontext已经是UOW模式和存储库模式的组合: https ://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext( v= vs.103)的.aspx
因此,如果dbcontext已经解决了这些模式解决的问题,为什么要用EF5重新实现这些模式呢?
此外,在本教程中,UnitOfWork类似乎没有显示UOW应该给出的任何好处。 例如,它声明:“这样,当一个工作单元完成后,您可以在该上下文实例上调用SaveChanges方法,并确保所有相关更改都将得到协调。”
但它似乎只是无缘无故地包装dbcontext。 我想我错过了一些东西。 我没有看到在这个实现中有任何协调……如果出现问题,事情如何“回滚”?
不要使用其他UoW /存储库抽象层
正如OP正确指出的那样,Entity Framework(类似于NHibernate和其他ORM)已经为您提供了数据库的抽象,同时提供了可供您使用的事务“工作单元”和“存储库”。
额外的UoW /存储库抽象层是反模式 ,应该不惜一切代价避免。 它有很多问题,其中最重要的是:
- 它们阻止你使用底层ORM的全部function(延迟加载,急切加载,复杂查询……)
- 如果他们想要提供除简单CRUD之外的任何额外好处,它们将会泄漏(即反映基础ORM中存在的function)。
但是,但是,但……
我需要通过模拟我的存储库来进行unit testing
不,你没有。 只需使用具有特定内容的数据库即可进行测试。 如果您希望更快,请使用内存数据库(例如SQLite, Effort ,…)。
EF不强制执行未在数据关系中表达的业务逻辑……要强制执行此类逻辑,您必须围绕EF上下文构建某种OUW / Repository /。
不,你不应该。 在基础架构抽象层(例如工作单元或存储库)中实现业务逻辑是完全错误的。
- 有价值的业务逻辑属于域实体,域服务,域命令或长期运行的业务流程,sagas。
- 简单的validation(即非
null
,x
和y
之间的值)不会:那些应该在系统接口边界解决。
还要注意,没有任何有价值的业务逻辑的简单CRUD样式操作不需要经历所有“层箍”,即避免这种模式:
- 数据库→无行为的实体→DTO→查看模型→查看
- 编辑字段
- 查看→查看模型→DTO→无行为的实体→数据库
只需从控制器中的ORM直接加载视图所需的“视图模型”形状,然后直接从控制器中保存。
关于抽象
不必要的抽象和诸如此类的层层箍是邪恶的。 它们会混淆您的代码,绑定您的手,泄漏,增加代码大小,从而增加代码中的错误数量,而不会提供任何附加值。
当它们为您提供附加值时使用抽象,例如,当您需要它们来解决跨领域问题,捕获/管理架构中的重复模式时,……
为抽象而创建抽象是浪费时间。
我已经在这里写了很多文章,但我会总结一下你的利益。 是的,entity framework已经实现了UoW( DbContext
)和存储库( DbSet
)模式。 重新实施它们没有任何好处。 实际上,由于它大大增加了项目的维护开销,因此会产生很大的不利影响。
为什么Microsoft在入门教程中包含了这个? 老实说,我不确定,但这是一个困扰无数新MVC开发人员的错误,当我刚开始时,我自己也包括在内。
在某种抽象中有好处,这样您的项目就不依赖于任何一种获取数据的特定方式。 但是,这种抽象应该返回您的操作所需的特定数据,不多也不少。 由于缺乏一个更好的词,我将其称为“服务”,尽管微软通过SOA嫁接了这个词的不同含义。 简单地说,就像您只是为应用程序创建API一样,就像创建Web API一样,只是完全基于代码(不需要实际的HTTP连接)。 然后进入您的项目可以引用的DAL层(类库或类似)。
关于EF的事情是它暴露的OUW或Repositoryfunction中没有业务逻辑。 如果您调用SaveChanges,它将很乐意保存所有更改。 但是,有一个要求是,当添加说Widget时,为Widget添加Frobber是必要的,你运气不好(除非涉及到FK依赖)。 对于未在数据关系中表达的任何业务逻辑,开箱即用的EF不会强制执行。
要强制执行此类逻辑,您必须围绕EF上下文构建一个OUW / Repository /。 根据我的知识,这是你做这件事的唯一原因。
工作单元和存储库模式与entity framework工作无关。 它是设计模式之一。 因此它用于使您的代码更具可读性,可重用性和高效性,并且这些模式也用于实现singelton(一次性对象实例化)以及避免反转控制。