ADO.NET 如何使用存储库和工作单元模式?
How to use Repository and Unit of Work Patterns with ADO.NET?
我正在构建 ASP.NET MVC 5 应用程序。
我了解了存储库和工作单元 (UoW) 模式 here。
这些示例使用 Entity Framework,它本身添加了高级抽象。
我正在使用 ADO.NET 而不是 EF。我想知道:
- Repository 和 UoW 模式是否对 ADO.NET 有意义?
- 我的存储库和 UoW 在 ADO.NET 中看起来如何?有样品吗?
- 我可以为 Repository 添加一个单独的 class 库或使其成为 DAL 的一部分吗?
- 当您谈论标准时,工作单元模式更为重要 ADO.NET 因为您必须绝对确保您打开的连接仅在要求的时间段内打开,已实现通过将连接包装在
using
语句中。
- ADO.NET 中的工作单元看起来像这样:
using (SqlConnection con = new SqlConnection(//connection string)
{
using (SqlCommand cmd = new SqlCommand(storedProcname, con))
{
//...
}
}
当您使用 using
语句来包含您的工作单元时,您可以放心,在后台 SqlConnection.Dispose()
调用 SqlConnection.Close()
方法,并且 SqlCommand.Dispose()
呼叫 SqlCommand.Close()
.
- 正如您在上一个问题中所回答的,如果您愿意,可以将这两者分开,但我个人认为它们应该是同一回事。
如果您查看 definitions 模式以及支持它们所需的模式,您会发现,如果您开始自己实施它们,您将永远不会远离创造你自己的 ORM。虽然这是一项令人着迷的任务,但当您考虑 NHibernate 和 EntityFramework.
时,它永远不值得
但是,为了回答您的问题,我发现 Fowler 的 PoEAA 书对学习如何编写我自己的 UoW、DataMappers 和 Repositories 非常宝贵,所有这些都基于 ADO.Net。它是由显然是真实完成的人编写的,犯了所有错误,然后将它们记录下来,这样您就不必这样做了。我没有读过您链接的文章,但我经常对使用此类文章持谨慎态度,因为它们仅展示了对此类模式的表面考虑。
我写了一篇 blog post,它教您如何编写独立于驱动程序的代码以及如何使用普通 ADO.NET.
实现 Uow/Repository 模式
包含在这个答案中有点太长了,但基本上 IDbtransaction
将代表您的工作单元(或包含在一个单元中)并且每个存储库都将在其构造函数中采用事务或 UoW。
使用 IDbTransaction
创建命令
using (var cmd = transaction.Connection.CreateCommand())
{
cmd.Transaction = transaction;
//do a CRUD operation here.
}
前段时间我写了一篇文章 blog post 为什么您链接的那个教程是有害的。 tldr;存储库使用实现 UoW 的 DAO,但存储库不应该是 UoW 的一部分。除非你想让你的代码复杂化 base/life.
回答您的问题:
- 一旦您使用 EF 或任何其他 ORM,UoW 就会自动在那里实现。如果你走微 ORM 路径(没有正当理由直接使用 ado.net),UoW 基本上是 db 事务。存储库应始终处理应用程序对象,从不 处理 ORM(持久性)对象。如果你的应用程序对象被用作持久化实体,那么你可能有一个标准的 CRUD 应用程序,你并不真的需要存储库模式。对于简单的应用程序,直接使用ORM(它节省了大量时间)。
- 存储库使用实现 UoW 的 DAO 作为实现细节。应用程序的其余部分不知道存储库(界面)本身之外的任何内容。
- 存储库接口在使用它的地方定义(通常是 Domain/Business 层)。存储库 实现 是 DAL 的一部分。请注意,您应该仅使用存储库 来更改模型 (create/update/delete)。对于查询,让 query services (objects) 处理特定用例并直接与数据库一起使用会更容易和可维护。
有很多滥用存储库模式的地方,我建议阅读我的 "Repository for dummies" post 以了解这是一个非常简单的模式,与您通常使用的复杂示例无关看到了。
我正在构建 ASP.NET MVC 5 应用程序。
我了解了存储库和工作单元 (UoW) 模式 here。
这些示例使用 Entity Framework,它本身添加了高级抽象。
我正在使用 ADO.NET 而不是 EF。我想知道:
- Repository 和 UoW 模式是否对 ADO.NET 有意义?
- 我的存储库和 UoW 在 ADO.NET 中看起来如何?有样品吗?
- 我可以为 Repository 添加一个单独的 class 库或使其成为 DAL 的一部分吗?
- 当您谈论标准时,工作单元模式更为重要 ADO.NET 因为您必须绝对确保您打开的连接仅在要求的时间段内打开,已实现通过将连接包装在
using
语句中。 - ADO.NET 中的工作单元看起来像这样:
using (SqlConnection con = new SqlConnection(//connection string)
{
using (SqlCommand cmd = new SqlCommand(storedProcname, con))
{
//...
}
}
当您使用 using
语句来包含您的工作单元时,您可以放心,在后台 SqlConnection.Dispose()
调用 SqlConnection.Close()
方法,并且 SqlCommand.Dispose()
呼叫 SqlCommand.Close()
.
- 正如您在上一个问题中所回答的,如果您愿意,可以将这两者分开,但我个人认为它们应该是同一回事。
如果您查看 definitions 模式以及支持它们所需的模式,您会发现,如果您开始自己实施它们,您将永远不会远离创造你自己的 ORM。虽然这是一项令人着迷的任务,但当您考虑 NHibernate 和 EntityFramework.
时,它永远不值得但是,为了回答您的问题,我发现 Fowler 的 PoEAA 书对学习如何编写我自己的 UoW、DataMappers 和 Repositories 非常宝贵,所有这些都基于 ADO.Net。它是由显然是真实完成的人编写的,犯了所有错误,然后将它们记录下来,这样您就不必这样做了。我没有读过您链接的文章,但我经常对使用此类文章持谨慎态度,因为它们仅展示了对此类模式的表面考虑。
我写了一篇 blog post,它教您如何编写独立于驱动程序的代码以及如何使用普通 ADO.NET.
实现 Uow/Repository 模式包含在这个答案中有点太长了,但基本上 IDbtransaction
将代表您的工作单元(或包含在一个单元中)并且每个存储库都将在其构造函数中采用事务或 UoW。
使用 IDbTransaction
using (var cmd = transaction.Connection.CreateCommand())
{
cmd.Transaction = transaction;
//do a CRUD operation here.
}
前段时间我写了一篇文章 blog post 为什么您链接的那个教程是有害的。 tldr;存储库使用实现 UoW 的 DAO,但存储库不应该是 UoW 的一部分。除非你想让你的代码复杂化 base/life.
回答您的问题:
- 一旦您使用 EF 或任何其他 ORM,UoW 就会自动在那里实现。如果你走微 ORM 路径(没有正当理由直接使用 ado.net),UoW 基本上是 db 事务。存储库应始终处理应用程序对象,从不 处理 ORM(持久性)对象。如果你的应用程序对象被用作持久化实体,那么你可能有一个标准的 CRUD 应用程序,你并不真的需要存储库模式。对于简单的应用程序,直接使用ORM(它节省了大量时间)。
- 存储库使用实现 UoW 的 DAO 作为实现细节。应用程序的其余部分不知道存储库(界面)本身之外的任何内容。
- 存储库接口在使用它的地方定义(通常是 Domain/Business 层)。存储库 实现 是 DAL 的一部分。请注意,您应该仅使用存储库 来更改模型 (create/update/delete)。对于查询,让 query services (objects) 处理特定用例并直接与数据库一起使用会更容易和可维护。
有很多滥用存储库模式的地方,我建议阅读我的 "Repository for dummies" post 以了解这是一个非常简单的模式,与您通常使用的复杂示例无关看到了。