ASP.NET Boilerplate 自定义存储库与数据库对象使用指南

在本文中,将探讨如何在ASP.NET Boilerplate框架中创建自定义存储库,并利用存储过程、视图和用户定义函数来执行数据库操作。ASP.NET Boilerplate是一个模块化的、多租户的、可扩展的框架,用于构建基于ASP.NET Core的应用程序。为了更深入地了解这个框架,建议参考其官方文档。

要开始使用ASP.NET Boilerplate框架,可以从下载一个启动模板。本文以ASP.NET Core和多页面Web应用程序为例,项目名为Acme.PhoneBook。如果需要帮助来设置模板,可以查看。

创建自定义存储库

将创建一个自定义存储库,以便使用存储过程、视图和用户定义函数对用户实体执行一些基本操作。要实现自定义存储库,只需从应用程序特定的基存储库类派生。

在领域层(Acme.PhoneBook.Core)中实现接口。

public interface IUserRepository : IRepository { // ... }

在基础设施层(Acme.PhoneBook.EntityFrameworkCore)中实现存储库。

public class UserRepository : PhoneBookRepositoryBase, IUserRepository { private readonly IActiveTransactionProvider _transactionProvider; public UserRepository(IDbContextProvider dbContextProvider, IActiveTransactionProvider transactionProvider) : base(dbContextProvider) { _transactionProvider = transactionProvider; } // ... }

辅助方法

首先,创建一些辅助方法,这些方法将由其他方法共享,以执行一些常见的任务:

private DbCommand CreateCommand(string commandText, CommandType commandType, params SqlParameter[] parameters) { var command = Context.Database.GetDbConnection().CreateCommand(); command.CommandText = commandText; command.CommandType = commandType; command.Transaction = GetActiveTransaction(); foreach (var parameter in parameters) { command.Parameters.Add(parameter); } return command; } private void EnsureConnectionOpen() { var connection = Context.Database.GetDbConnection(); if (connection.State != ConnectionState.Open) { connection.Open(); } } private DbTransaction GetActiveTransaction() { return (DbTransaction)_transactionProvider.GetActiveTransaction( new ActiveTransactionProviderArgs { { "ContextType", typeof(PhoneBookDbContext) }, { "MultiTenancySide", MultiTenancySide } }); }

存储过程

下面是一个存储过程调用示例,用于获取所有用户的用户名。将此添加到存储库实现中(UserRepository)。

public async Task> GetUserNames() { EnsureConnectionOpen(); using (var command = CreateCommand("GetUsernames", CommandType.StoredProcedure)) { using (var dataReader = await command.ExecuteReaderAsync()) { var result = new List(); while (dataReader.Read()) { result.Add(dataReader["UserName"].ToString()); } return result; } } }

在IUserRepository中定义GetUserNames方法:

public interface IUserRepository : IRepository { // ... Task> GetUserNames(); // ... }

下面是被调用的存储过程:

USE [PhoneBookDb] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [dbo].[GetUsernames] AS BEGIN SET NOCOUNT ON; SELECT UserName FROM AbpUsers END GO

在应用程序服务中使用存储过程

现在已经实现了从数据库调用存储过程的函数。让在应用程序服务中使用它:

public class UserAppService : AsyncCrudAppService, IUserAppService { private readonly IUserRepository _userRepository; public UserAppService(..., IUserRepository userRepository) : base(repository) { ... _userRepository = userRepository; } ... public async Task> GetUserNames() { return await _userRepository.GetUserNames(); } }

下面是另一个示例,它向存储过程发送一个参数以删除用户:

public async Task DeleteUser(EntityDto input) { await Context.Database.ExecuteSqlCommandAsync( "EXEC DeleteUserById @id", default(CancellationToken), new SqlParameter("id", input.Id)); }

被调用的删除用户的存储过程:

USE [PhoneBookDb] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [dbo].[DeleteUserById] @id int AS BEGIN SET NOCOUNT ON; DELETE FROM AbpUsers WHERE [Id] = @id END GO

另一个示例是发送一个参数来更新用户的电子邮件地址:

public async Task UpdateEmail(UpdateEmailDto input) { await Context.Database.ExecuteSqlCommandAsync( "EXEC UpdateEmailById @email, @id", default(CancellationToken), new SqlParameter("id", input.Id), new SqlParameter("email", input.EmailAddress)); }

被调用的更新方法的存储过程:

USE [PhoneBookDb] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [dbo].[UpdateEmailById] @email nvarchar(256), @id int AS BEGIN SET NOCOUNT ON; UPDATE AbpUsers SET [EmailAddress] = @email WHERE [Id] = @id END GO

视图

可以这样调用一个视图:

public async Task> GetAdminUsernames() { EnsureConnectionOpen(); using (var command = CreateCommand("SELECT * FROM dbo.UserAdminView", CommandType.Text)) { using (var dataReader = await command.ExecuteReaderAsync()) { var result = new List(); while (dataReader.Read()) { result.Add(dataReader["UserName"].ToString()); } return result; } } }

此方法的视图:

SELECT * FROM dbo.AbpUsers WHERE (Name = 'admin')

用户定义函数

可以这样调用用户定义函数:

public async Task GetUserById(EntityDto input) { EnsureConnectionOpen(); using (var command = CreateCommand("SELECT dbo.GetUsernameById(@id)", CommandType.Text, new SqlParameter("@id", input.Id))) { var username = (await command.ExecuteScalarAsync()).ToString(); return new GetUserByIdOutput() { Username = username }; } } USE [PhoneBookDb] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE FUNCTION [dbo].[GetUsernameById] @id int RETURNS nvarchar(32) AS BEGIN DECLARE @username nvarchar(32) SELECT @username = [UserName] FROM AbpUsers WHERE [ID] = @id RETURN @username END GO
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485