7

我正在构建ASP.NET MVC 5应用程序。如何在ADO.NET中使用存储库和工作单元模式?

我读过关于版本库和工作单元(UoW)模式here

这些示例使用实体框架,它本身添加了高级抽象。

我使用ADO.NET而不是EF。我想知道:

  1. Repository和UoW模式是否对ADO.NET有意义?
  2. 我的存储库和UoW将如何使用ADO.NET进行查看?任何样品?
  3. 我可以为Repository添加一个单独的类库,还是使其成为DAL的一部分?

回答

5

我写了一个blog post,教你如何编写驱动程序无关的代码,以及如何用普通的ADO.NET实现Uow/Repository模式。

包含在这个答案中有点太长,但基本上IDbtransaction将代表你的单元工作(或被包含在一个单元中),并且每个存储库都将在其构造函数中使用事务或UoW。

要使用IDbTransaction

using (var cmd = transaction.Connection.CreateCommand()) 
{ 
    cmd.Transaction = transaction; 

    //do a CRUD operation here. 
} 
+1

感谢这个例子,但是如何使用一个DI容器(例如ninject)作为存储库,以及对于工厂来说,在WebApi/MVC项目中如何呢?作为回购的需要他们的乌实例被实例化 – eddy

+0

'yourContainer.RegisterService (container => container.Resolve ()。BeginTransaction());' – jgauffin

+0

@jgauffin我读了[你的这篇文章](http ://blog.gauffin.org/2014/01/unit-of-work-sample-implementation-for-ado-net/)我遇到了几个问题:1)创建交易是否有任何性能损失当你只是阅读(选择)数据? 2)IUnitOfWork的实现细节是什么?你能告诉我们它的代码吗?谢谢。 – Axel

1
  1. 工作模式的单位是当你在谈论标准ADO.NET,因为你必须绝对确保你打开的连接是只开放所要求的时间段更重要的是,通过在using声明中包装连接来实现。在ADO.NET工作
  2. 股将是这个样子:

using (SqlConnection con = new SqlConnection(//connection string) { using (SqlCommand cmd = new SqlCommand(storedProcname, con)) { //... } }

当你使用using语句包括你的工作单位,您可以放心的是,引擎盖下SqlConnection.Dispose()调用SqlConnection.Close()方法,并且SqlCommand.Dispose()调用SqlCommand.Close()

  1. 正如您在上一个问题中所回答的,如果您希望这样做,您可以将这两者分开,但我个人认为它们应该是同一件事。
1

如果你看看图案的definitions,以及支持它们所需的模式,你会看到,如果你开始自己实现这些功能,你将永远不会被创建自己的ORM远远徘徊。虽然这是一项非常吸引人的任务,但在考虑NHibernate和EntityFramework时,这绝对不值得。

但是,为了回答你的问题,我发现Fowler的PoEAA这本书在学习如何编写我自己的UoW,DataMapper和存储库(全都基于ADO.Net)方面是非常宝贵的。它是由某个人写的,他明显地做了真正的事,犯了所有的错误,然后记录下来,这样你就不必这样做了。我没有阅读过你曾经链接过的文章,但是我经常对使用这样的文章持谨慎态度,因为他们只是展示了像这样的模式的表层考虑。

1

前一段时间我写了一个blog post为什么很教程中,您链接是有害的创建命令。 tldr;一个存储库使用一个实现UoW的DAO,但该存储库不应该是UoW的一部分。除非你喜欢让你的代码库/生活复杂化。

回答您的问题:

  1. 一旦你使用EF或任何其他ORM,UOW会自动执行那里。如果你使用微ORM路径(没有直接使用ado.net的合理理由),UoW基本上就是db事务。一个仓库应该总是处理应用程序对象,从不与ORM(持久性)对象。如果您的应用程序对象用作持久性实体,那么您可能有一个标准的CRUD应用程序,并且您并不需要存储库模式。对于简单的应用程序,直接使用ORM(它可以节省大量时间)。
  2. 存储库利用实现UoW的DAO作为实现细节。应用程序的其余部分不知道存储库(接口)本身之外的任何内容。
  3. 存储库接口定义在何处(通常是域/业务层)。存储库实现是DAL的一部分。请注意,您应该使用存储库只有用于更改模型(创建/更新/删除)。对于查询,让query services (objects)处理特定用例以及直接与db一起使用会更容易和可维护。

有很多滥用存储库模式的地方,我建议阅读我的"Repository for dummies"文章,了解这是一个非常简单的模式,与您通常看到的复杂示例无关。

+0

我喜欢你的博客文章的方式,你从业务或领域层的角度解释它,但是,有一件事让我感到困惑。当你说:“这就是为什么所有存储库接口都驻留在业务层中,而他们的具体实现是持久层(DAL)的一部分。”,你是在同一个项目还是不同的项目中讨论Business和DAL?如果不同的项目不会创建循环引用?因为DAL层中的具体实现需要引用接口的业务层.. – user20358

+0

...并且业务层需要引用DAL层以获取它所具有的接口的具体实现。 – user20358

+0

@ user20358没关系。 '层'只是一个逻辑上下文。关键是回购实现位于另一个领域,而不是领域,基本上是基础架构的一部分。 – MikeSW

相关问题