如何在ADO.NET中使用Repository和Unit of Work Patterns?

时间:2022-09-22 23:52:14

I am building ASP.NET MVC 5 application.

我正在构建ASP.NET MVC 5应用程序。

I read about Repository and Unit of Work (UoW) Patterns here.

我在这里阅读了关于存储库和工作单元(UoW)模式的内容。

These examples use Entity Framework which adds a high-level of abstraction itself.

这些示例使用Entity Framework,它本身添加了高级抽象。

I am using ADO.NET and not EF. I want to know:

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

  1. Whether Repository and UoW patterns makes any sense with ADO.NET?
  2. Repository和UoW模式是否与ADO.NET有任何关系?
  3. How will my Repositories and UoW look with ADO.NET? Any Samples?
  4. 我的存储库和UoW如何看待ADO.NET?任何样品?
  5. Can I add a separate class library for Repository or to make it a part of DAL?
  6. 我可以为Repository添加单独的类库还是使其成为DAL的一部分?

4 个解决方案

#1


5  

I've written a blog post which teaches you on how to write driver independent code and how to implement Uow/Repository pattern with plain ADO.NET.

我写了一篇博客文章,教你如何编写与驱动程序无关的代码,以及如何使用普通的ADO.NET实现Uow / Repository模式。

It's a bit too long to include in this answer, but basically the IDbtransaction will represent your Unit oF Work (or be contained in one) and every repository will take the transaction or UoW in it's constructor.

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

To create a command using a IDbTransaction

使用IDbTransaction创建命令

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

    //do a CRUD operation here.
}

#2


1  

If you look at the definitions of the patterns, and the patterns required to support them, you'll see that, if you start to implement them yourself, you'll never be wandering far from creating your own ORM. While this is a fascinating task, it's never worth it when you consider NHibernate and EntityFramework.

如果你看一下模式的定义,以及支持它们所需的模式,你会发现,如果你自己开始实现它们,你将永远不会远离创建自己的ORM。虽然这是一项非常有趣的任务,但在考虑NHibernate和EntityFramework时,它永远不值得。

However, to answer your question, I found Fowler's PoEAA book invaluable in learning how to write my own UoW, DataMappers and Repositories, all based on ADO.Net. It's written by someone who's obviously done it for real, made all the mistakes and then documented them so that you don't have to. I haven't read the article you've linked, however I'm often wary of using articles like this as they only demonstrate a surface-level consideration of patterns like this.

然而,为了回答你的问题,我发现Fowler的PoEAA书在学习如何编写我自己的UoW,DataMappers和Repositories方面非常宝贵,所有这些都基于ADO.Net。它是由一个显然是真实地完成它的人写的,犯了所有的错误然后记录下来,这样你就不必这样做了。我没有读过您链接过的文章,但是我经常对使用这样的文章保持警惕,因为它们只表现出对此类模式的表面层次考虑。

#3


1  

  1. The Unit of Work pattern is more important when you're talking about standard ADO.NET because you have to make absolutely sure that the connections you're opening are only open for the required period of time, achieved by wrapping connections inside using statements.
  2. 当您谈论标准ADO.NET时,工作单元模式更为重要,因为您必须确保您打开的连接仅在所需的时间段内打开,通过使用语句包装连接来实现。
  3. Unit of Work in ADO.NET would look something like this:
  4. ADO.NET中的工作单元看起来像这样:

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

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

As you're using using statements to encompass your unit of work, you can be assured that under the hood SqlConnection.Dispose() calls the SqlConnection.Close() method, and SqlCommand.Dispose() calls SqlCommand.Close().

当您使用using语句来包含您的工作单元时,您可以放心,SqlConnection.Dispose()调用SqlConnection.Close()方法,SqlCommand.Dispose()调用SqlCommand.Close()。

  1. As answered in your previous question, you can separate these two out if you wish to do so, but personally I think they should be the same thing.
  2. 正如您在上一个问题中所回答的那样,如果您愿意,可以将这两个分开,但我个人认为它们应该是相同的。

#4


1  

Some time ago I wrote a blog post why that very tutorial you've linked is harmful . tldr; a repository uses a DAO implementing UoW, but the repository should not be part of a UoW. Unless you like to complicate your code base/life.

前段时间我写了一篇博客文章,为什么你所链接的教程是有害的。 tldr;存储库使用实现UoW的DAO,但存储库不应该是UoW的一部分。除非您想使代码库/生活复杂化。

To answer your questions:

回答你的问题:

  1. Once you're using EF or any other ORM, UoW is automatically implemented there. If you go the micro-ORM path (there is no valid reason to use ado.net directly) , the UoW is basically the db transaction. A repository should always deal with application objects, never with ORM (persistence) objects. If your app objects are used as persistence entities, then you probably have a standard CRUD app, and you don't really need the repository pattern. For simple apps, use the ORM directly (it saves a lot of time).
  2. 一旦您使用EF或任何其他ORM,UoW就会自动在那里实施。如果你去micro-ORM路径(没有正当理由直接使用ado.net),UoW基本上就是db事务。存储库应该始终处理应用程序对象,而不是处理ORM(持久性)对象。如果您的应用程序对象用作持久性实体,那么您可能有一个标准的CRUD应用程序,并且您并不真正需要存储库模式。对于简单的应用程序,直接使用ORM(它可以节省大量时间)。
  3. A Repository makes use of a DAO implementing UoW as an implementation detail. The rest of the app isn't aware of anything outside the repository (interface) itself.
  4. 存储库使用实现UoW的DAO作为实现细节。应用程序的其余部分不知道存储库(接口)本身之外的任何内容。
  5. A repository interface is defined where it's used (usually a the Domain/Business layer). The repository implementation is part of the DAL. Note that you should use repositories only for changing the model (create/update/delete). For queries, it's much easier and maintainable to have query services (objects) handling a specific use cases and which work with the db directly.
  6. 存储库接口定义在其使用的位置(通常是域/业务层)。存储库实现是DAL的一部分。请注意,您应仅使用存储库来更改模型(创建/更新/删除)。对于查询,使查询服务(对象)处理特定用例并直接使用db更容易和可维护。

There's a a LOT of misusing the repository pattern out there, I suggest reading my "Repository for dummies" post to understand that's a very simple pattern which has nothing to do with the complicated examples you're usually seeing.

有很多滥用存储库模式的内容,我建议阅读我的“傻瓜存储库”帖子,以了解这是一个非常简单的模式,与您经常看到的复杂示例无关。

#1


5  

I've written a blog post which teaches you on how to write driver independent code and how to implement Uow/Repository pattern with plain ADO.NET.

我写了一篇博客文章,教你如何编写与驱动程序无关的代码,以及如何使用普通的ADO.NET实现Uow / Repository模式。

It's a bit too long to include in this answer, but basically the IDbtransaction will represent your Unit oF Work (or be contained in one) and every repository will take the transaction or UoW in it's constructor.

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

To create a command using a IDbTransaction

使用IDbTransaction创建命令

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

    //do a CRUD operation here.
}

#2


1  

If you look at the definitions of the patterns, and the patterns required to support them, you'll see that, if you start to implement them yourself, you'll never be wandering far from creating your own ORM. While this is a fascinating task, it's never worth it when you consider NHibernate and EntityFramework.

如果你看一下模式的定义,以及支持它们所需的模式,你会发现,如果你自己开始实现它们,你将永远不会远离创建自己的ORM。虽然这是一项非常有趣的任务,但在考虑NHibernate和EntityFramework时,它永远不值得。

However, to answer your question, I found Fowler's PoEAA book invaluable in learning how to write my own UoW, DataMappers and Repositories, all based on ADO.Net. It's written by someone who's obviously done it for real, made all the mistakes and then documented them so that you don't have to. I haven't read the article you've linked, however I'm often wary of using articles like this as they only demonstrate a surface-level consideration of patterns like this.

然而,为了回答你的问题,我发现Fowler的PoEAA书在学习如何编写我自己的UoW,DataMappers和Repositories方面非常宝贵,所有这些都基于ADO.Net。它是由一个显然是真实地完成它的人写的,犯了所有的错误然后记录下来,这样你就不必这样做了。我没有读过您链接过的文章,但是我经常对使用这样的文章保持警惕,因为它们只表现出对此类模式的表面层次考虑。

#3


1  

  1. The Unit of Work pattern is more important when you're talking about standard ADO.NET because you have to make absolutely sure that the connections you're opening are only open for the required period of time, achieved by wrapping connections inside using statements.
  2. 当您谈论标准ADO.NET时,工作单元模式更为重要,因为您必须确保您打开的连接仅在所需的时间段内打开,通过使用语句包装连接来实现。
  3. Unit of Work in ADO.NET would look something like this:
  4. ADO.NET中的工作单元看起来像这样:

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

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

As you're using using statements to encompass your unit of work, you can be assured that under the hood SqlConnection.Dispose() calls the SqlConnection.Close() method, and SqlCommand.Dispose() calls SqlCommand.Close().

当您使用using语句来包含您的工作单元时,您可以放心,SqlConnection.Dispose()调用SqlConnection.Close()方法,SqlCommand.Dispose()调用SqlCommand.Close()。

  1. As answered in your previous question, you can separate these two out if you wish to do so, but personally I think they should be the same thing.
  2. 正如您在上一个问题中所回答的那样,如果您愿意,可以将这两个分开,但我个人认为它们应该是相同的。

#4


1  

Some time ago I wrote a blog post why that very tutorial you've linked is harmful . tldr; a repository uses a DAO implementing UoW, but the repository should not be part of a UoW. Unless you like to complicate your code base/life.

前段时间我写了一篇博客文章,为什么你所链接的教程是有害的。 tldr;存储库使用实现UoW的DAO,但存储库不应该是UoW的一部分。除非您想使代码库/生活复杂化。

To answer your questions:

回答你的问题:

  1. Once you're using EF or any other ORM, UoW is automatically implemented there. If you go the micro-ORM path (there is no valid reason to use ado.net directly) , the UoW is basically the db transaction. A repository should always deal with application objects, never with ORM (persistence) objects. If your app objects are used as persistence entities, then you probably have a standard CRUD app, and you don't really need the repository pattern. For simple apps, use the ORM directly (it saves a lot of time).
  2. 一旦您使用EF或任何其他ORM,UoW就会自动在那里实施。如果你去micro-ORM路径(没有正当理由直接使用ado.net),UoW基本上就是db事务。存储库应该始终处理应用程序对象,而不是处理ORM(持久性)对象。如果您的应用程序对象用作持久性实体,那么您可能有一个标准的CRUD应用程序,并且您并不真正需要存储库模式。对于简单的应用程序,直接使用ORM(它可以节省大量时间)。
  3. A Repository makes use of a DAO implementing UoW as an implementation detail. The rest of the app isn't aware of anything outside the repository (interface) itself.
  4. 存储库使用实现UoW的DAO作为实现细节。应用程序的其余部分不知道存储库(接口)本身之外的任何内容。
  5. A repository interface is defined where it's used (usually a the Domain/Business layer). The repository implementation is part of the DAL. Note that you should use repositories only for changing the model (create/update/delete). For queries, it's much easier and maintainable to have query services (objects) handling a specific use cases and which work with the db directly.
  6. 存储库接口定义在其使用的位置(通常是域/业务层)。存储库实现是DAL的一部分。请注意,您应仅使用存储库来更改模型(创建/更新/删除)。对于查询,使查询服务(对象)处理特定用例并直接使用db更容易和可维护。

There's a a LOT of misusing the repository pattern out there, I suggest reading my "Repository for dummies" post to understand that's a very simple pattern which has nothing to do with the complicated examples you're usually seeing.

有很多滥用存储库模式的内容,我建议阅读我的“傻瓜存储库”帖子,以了解这是一个非常简单的模式,与您经常看到的复杂示例无关。