在大多数业务应用程序,您将从数据存储和检索数据存储通过执行CRUD操作(创建、读取、更新和删除)。在这方面,有几个技术和工具可以使用。例如,您可以选择可用的ORM框架如实体框架,衣冠楚楚的,或者NHibernate。
然而,挑战超越存储和检索数据。您想要使用的工具或方法,帮助您编写可重用、可维护的、灵活的代码。,你可以利用设计模式存储库和工作单元等模式。
我们检查了仓库的设计模式在前面的文章在这里。在本文中,我们将探索工作单元设计模式与相关代码示例来演示这些概念。
使用本文中提供的代码示例,您应该Visual Studio 2022安装在您的系统。如果你不已经有一个副本,你可以在这里下载Visual Studio 2022。
创建一个ASP。网络核心7 Web API project in Visual Studio 2022
首先,让我们创建一个ASP。网络核心7 project in Visual Studio 2022. Follow these steps:
- 启动Visual Studio 2022 IDE。
- 点击“创建新项目。”
- 在“创建新项目”窗口中,选择“ASP。网络核心Web API” from the list of templates displayed.
- 单击Next。
- 在“配置您的新项目”窗口中,指定新项目的名称和位置。
- (可选)检查“解决方案和项目在同一个目录”复选框,根据您的喜好。
- 单击Next。
- 在“附加信息”窗口中,把复选框说“使用控制器(取消使用最少的api)”检查,因为我们不是在这个例子中使用最少的api。离开“验证类型”为“没有”(默认)。
- 确保复选框“启用开放API支持,”“为HTTPS,配置”和“使码头工人”是不受我们不会使用这些特性。
- 单击Create。
我们将使用ASP。网络核心7 Web API project to work with the unit of work design pattern in the sections below.
工作单元的设计模式是什么?
工作单元设计模式在应用中保证数据完整性和一致性。它确保所有应用程序中的多个对象所做的更改提交到数据库或回滚。它提供了一个有组织的和一致的方式来管理数据库更改和交易。
这种设计模式的主要目标是保持一致性和原子性,确保所有数据库更改成功或失败在一起如果有一个问题。因此,数据一致性维护,修改数据库总是准确的。工作单元的设计模式,开发人员可以节省时间和精力,专注于业务逻辑,而不是数据库访问和管理。
用c#实现工作单元的设计模式
实现工作单元的设计模式,您必须指定工作单元所支持的操作在一个接口或合同,然后在一个具体的类中实现这些方法。你可以利用你想使用的任何数据访问技术,如实体框架,衣冠楚楚的,或ADO.NET。
一个典型的工作单元实现将包括下面列出的组件:
- 工作单元的接口。工作单元将执行的操作是由合同或定义一个接口,它包含的所有方法的声明添加、更改和删除数据和提交或回滚更改数据库。
- 一个工作单元接口的具体实现。我们刚刚描述接口的具体实现。该实现将包括所有的操作进行任何交易或数据操作和操作回滚或提交更改。
- 存储库类及其接口。所需的代码来访问或修改数据存储库中包含的类和接口。换句话说,你应该有一个类库使用的每个接口的方法和一个接口,用于存储库,用于指定允许的行为。
所以,让我们开始吧!
创建一个CustomDbContext类
在实体框架或实体框架核心,DbContext代表了网关到数据库。以下是DbContext类,可以自动生成,当你使用实体框架的核心。几次我们将使用这个类的代码片段。
公共类CustomDbContext: DbContext{公共CustomDbContext (DbContextOptions < CustomDbContext >选项):基础(选项){}保护覆盖空白OnConfiguring (DbContextOptionsBuilder optionsBuilder){}保护覆盖空白OnModelCreating (ModelBuilder ModelBuilder){}公共DbSet <作者>作者{得到;设置;}}
为工作单元定义的接口
创建一个新的名叫IUnitOfWork cs文件。在您的项目中cs和输入以下代码。
公共接口IUnitOfWork: IDisposable{空白Commit ();空白Rollback ();IRepository < T >库< T > (), T:类;}
实现工作单元的具体类
接下来,您应该创建IUnitOfWork接口的具体实现。为此,创建一个新类称为UnitOfWork cs扩展文件拥有相同的名称,并输入以下代码。
公开课UnitOfWork: IUnitOfWork IDisposable{私人只读的DbContext _dbContext;私人bool _disposed;公共UnitOfWork (DbContext DbContext) {_dbContext = DbContext;}公共空Commit () {_dbContext.SaveChanges ();}公共空Rollback () {foreach (var进入_dbContext.ChangeTracker.Entries()){开关(entry.State) {EntityState。补充:条目。状态= EntityState.Detached;打破;公共IRepository}}} < T >库< T > (), T:类{返回新的存储库< T > (_dbContext);}私人bool处理= false;保护虚拟空间处理(bool处理){如果(! this.disposed){(处理){_dbContext.Dispose (); } } this.disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } }
定义存储库接口
设计模式简化了数据访问存储库通过抽象的逻辑从其他应用程序的组件和模块。对象将被持久化没有你的工作直接与逻辑用于访问底层数据库。换句话说,存储库封装了逻辑用于访问数据源。
下一步是为存储库定义的接口。这个接口应该提供支持的声明的方法库。
创建一个名为IRepository的新接口在一个名为IRepository的文件。cs和用下面的代码替换默认生成的代码。
公共接口IRepository < T > T:类{T GetById(对象id);IList < T > GetAll ();空白添加实体(T);}
实现存储库接口
最后,您应该实现我们刚刚创建的存储库的接口。为此,创建一个新文件命名存储库。cs和用下面的代码替换默认生成的代码。
公共类库< T >: IRepository < T > T:类{私人只读的CustomDbContext _dbContext;私人只读的DbSet < T > _dbSet;公共T GetById(对象id){返回_dbSet.Find (id);}公共存储库(DbContext DbContext) {_dbContext = DbContext;_dbSet = _dbContext.Set < T > ();公共IList} < T > GetAll(){返回_dbSet.ToList ();}公共空白添加(T实体){_dbSet.Add(实体);}}
注册DbContext
作为奖励,你应该注册DbContext作为服务的项目。cs文件,这样您就可以利用依赖注入来索取DbContext实例库和UnitOfWork类。
有两种方法:使用AddDbContext方法或使用AddDbContextPool方法。AddDbContextPool方法是首选的,因为使用一个实例池将帮助您的应用程序的规模。
builder.Services.AddDbContextPool < CustomDbContext > (o = > o。UseSqlServer(“指定数据库连接字符串在这里……”));
在本文中,我们建立了一个通用存储库实现存储库,它使用一个IRepository接口和类。您可以创建一个存储库为一个特定的实体通过创建一个类,实现了通用IRepository < T >界面如下所示。
公共类AuthorRepository: IRepository <作者>{/ /编写代码来实现IRepository成员接口}
存储库和工作单元设计模式创建一个抽象层之间的业务逻辑和数据访问层,让开发人员的生活更加容易。工作单元模式使用单个事务或单个工作单元对多个insert、update和delete操作。这些操作要么成功要么失败作为整个单元。换句话说,所有的操作将作为一个事务提交或回滚成一个单一的单位。
而工作单元模式用于在单个事务中总几次手术,存储库封装了数据访问逻辑的代表类型,分离这一担忧从您的应用程序。