Asp.net mvc 如何在ADO.NET中使用存储库和工作单元模式?
我正在构建ASP.NETMVC5应用程序 我读过关于存储库和工作单元(UoW)模式的文章 这些示例使用实体框架,该框架本身添加了高级抽象 我使用的是ADO.NET而不是EF。我想知道:Asp.net mvc 如何在ADO.NET中使用存储库和工作单元模式?,asp.net-mvc,design-patterns,ado.net,repository-pattern,unit-of-work,Asp.net Mvc,Design Patterns,Ado.net,Repository Pattern,Unit Of Work,我正在构建ASP.NETMVC5应用程序 我读过关于存储库和工作单元(UoW)模式的文章 这些示例使用实体框架,该框架本身添加了高级抽象 我使用的是ADO.NET而不是EF。我想知道: 存储库和UoW模式对ADO.NET是否有意义 使用ADO.NET时,我的存储库和UoW的外观如何?有样品吗 我可以为存储库添加一个单独的类库,还是将其作为DAL的一部分 当您谈论标准ADO.NET时,工作单元模式更为重要,因为您必须绝对确保要打开的连接只在所需的时间段内打开,这是通过使用语句将连接包装在中实现的
中实现的
使用(SqlConnection con=newsqlconnection(//连接字符串)
{
使用(SqlCommand cmd=newsqlcommand(storedProcname,con))
{
//...
}
}
当您使用语句来包含您的工作单元时,您可以确信,在后台SqlConnection.Dispose()
调用SqlConnection.Close()
方法,而SqlCommand.Dispose()
调用SqlCommand.Close()
正如你在上一个问题中所回答的,如果你愿意的话,你可以把这两个分开,但我个人认为它们应该是一样的
如果你查看这些模式,以及支持它们的模式,你会发现,如果你自己开始实现它们,你就永远不会偏离创建自己的ORM。虽然这是一个令人着迷的任务,但是当你考虑NHiBiNATE和EntyTrimeStudio时,它永远不值得。
然而,为了回答你的问题,我发现福勒的书在学习如何编写基于ADO.Net的UoW、数据映射器和存储库方面非常有价值。这本书是由一位显然是真的这么做的人写的,他犯了所有错误,然后记录了这些错误,这样你就不必这么做了。我没有读过你链接的文章,但我经常读不要使用像这样的文章,因为它们只展示了像这样的模式的表面层次的考虑。
我已经写了一篇文章,教您如何编写独立于驱动程序的代码,以及如何使用普通ADO.NET实现Uow/存储库模式
这个答案中包含的内容有点太长,但基本上,IDbtransaction
将代表您的工作单元(或包含在一个工作单元中),并且每个存储库都将在其构造函数中包含该事务或UoW
使用IDbTransaction
using (var cmd = transaction.Connection.CreateCommand())
{
cmd.Transaction = transaction;
//do a CRUD operation here.
}
不久前,我写了一篇文章,解释了为什么您链接的教程是有害的。tldr;存储库使用DAO实现UoW,但存储库不应该是UoW的一部分。除非您想让代码库/生活复杂化
回答您的问题:
一旦您使用EF或任何其他ORM,UoW将自动在那里实现。如果您选择micro ORM路径(没有直接使用ado.net的有效理由),UoW基本上就是db事务。存储库应始终处理应用程序对象,从不使用ORM(持久性)对象。如果你的应用程序对象用作持久性实体,那么你可能有一个标准的CRUD应用程序,并且你并不真正需要存储库模式。对于简单的应用程序,直接使用ORM(它可以节省大量时间)
存储库使用实现UoW的DAO作为实现细节。应用程序的其余部分不知道存储库(接口)本身之外的任何内容
存储库接口是在使用它的地方定义的(通常是域/业务层)。存储库实现是DAL的一部分。请注意,您应该仅使用存储库来更改模型(创建/更新/删除).对于查询,处理特定用例和直接与db一起工作更容易和可维护
有很多人误用了存储库模式,我建议阅读我的文章,了解这是一个非常简单的模式,与您通常看到的复杂示例无关。我喜欢您的博客文章,您从业务或领域层的角度对其进行了解释,然而,有一件事让我感到失望当你说:“这就是为什么所有存储库接口都位于业务层,而它们的具体实现是持久层(DAL)的一部分。”,您是在同一个项目中还是在不同的项目中谈论业务和DAL?如果不同的项目,那么这不会创建循环引用吗?因为DAL层中的具体实现需要为接口引用业务层……而业务层需要为具体实现引用DAL层它拥有的接口的表示。@user20358这不重要。“层”只是一个逻辑上下文。关键是repo实现位于域以外的另一个上下文中,基本上是基础结构的一部分。@MikeSW“blog link”找不到。@vivek谢谢,我现在已经修复了。谢谢你的示例,但是你如何使用DI容器(例如ninject)来存储库,以及工厂,比如WebApi/MVC项目?因为repo需要实例化uow实例yourContainer.RegisterService(container=>container.Resolve().BeginTransaction());
@jgauffin我读到了,我有几个问题:1)即使只读取(选择)数据,也会对创建事务造成性能损失吗?2)IUnitOfWork的实现细节是什么?你能给我们看一下代码吗?谢谢。死链接,有人知道这篇文章的工作链接吗?