.net core 实例教程(八)事务提交配置、TransactionScope使用
小白浏览:5422024-03-18 14:05:34本文累计收益:0我也要赚钱

本文源码下载地址:http://www.80cxy.com/Blog/ResourceView?arId=202403191532545995NAAqJh

系列教程地址:http://www.80cxy.com/Blog/ArticleView?arId=202403191517574161ay3s5V

.net core 实例教程(三)仓储及领域服务功能实现(既实现用户表的增删改查接口)文章中讲解了数据库增删改查基本操作,数据库保存是在仓储代码中实现的。也没使用事务提交。本文讲解利用IAsyncActionFilter过滤器统计进行事务提交配置。

        public async Task<SysUser> AddUser(string userName, string password, string realName, string userType)
        {
            SysUser model = SysUser.Add(userName, password, realName, userType);
            await _dbContext.SysUser.AddAsync(model);
            await _dbContext.SaveChangesAsync();
            return model;
        }

一、UnitOfWorkFilter实现代码

using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;
using System.Transactions;

namespace SignUp.Common.ASPNETCore
{
    public class UnitOfWorkFilter : IAsyncActionFilter
    {
        private static UnitOfWorkAttribute? GetUoWAttr(ActionDescriptor actionDesc)
        {
            var caDesc = actionDesc as ControllerActionDescriptor;
            if (caDesc == null)
            {
                return null;
            }
            //try to get UnitOfWorkAttribute from controller,
            //if there is no UnitOfWorkAttribute on controller, 
            //try to get UnitOfWorkAttribute from action
            var uowAttr = caDesc.ControllerTypeInfo
                .GetCustomAttribute<UnitOfWorkAttribute>();
            //方法标注UnitOfWorkAttribute,进行事务控制
            if (uowAttr != null)
            {
                return uowAttr;
            }
            else
            {
                return caDesc.MethodInfo
                    .GetCustomAttribute<UnitOfWorkAttribute>();
            }
        }
        public async Task OnActionExecutionAsync(ActionExecutingContext context,
            ActionExecutionDelegate next)
        {
            var uowAttr = GetUoWAttr(context.ActionDescriptor);
            if (uowAttr == null)
            {
                await next();
                return;
            }
            using TransactionScope txScope = new(TransactionScopeAsyncFlowOption.Enabled);
            List<DbContext> dbCtxs = new List<DbContext>();
            foreach (var dbCtxType in uowAttr.DbContextTypes)
            {
                //用HttpContext的RequestServices
                //确保获取的是和请求相关的Scope实例
                var sp = context.HttpContext.RequestServices;
                DbContext dbCtx = (DbContext)sp.GetRequiredService(dbCtxType);
                dbCtxs.Add(dbCtx);
            }
            var result = await next();
            if (result.Exception == null)
            {
                foreach (var dbCtx in dbCtxs)
                {
                    await dbCtx.SaveChangesAsync();
                }
                txScope.Complete();
            }
        }
    }
}
using Microsoft.EntityFrameworkCore;

namespace SignUp.Common.ASPNETCore
{
    [AttributeUsage(AttributeTargets.Class
    | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class UnitOfWorkAttribute : Attribute
    {
        public Type[] DbContextTypes { get; init; }
        public UnitOfWorkAttribute(params Type[] dbContextTypes)
        {
            this.DbContextTypes = dbContextTypes;
            foreach (var type in dbContextTypes)
            {
                if (!typeof(DbContext).IsAssignableFrom(type))
                {
                    throw new ArgumentException($"{type} must inherit from DbContext");
                }
            }
        }
    }
}

二、使用方法

在需要事务提交的控制器或action上使用[UnitOfWork(typeof(SignUpDbContext))]特性即可。然后将仓储保存代码删除。

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SignUp.Common.ASPNETCore;
using SignUp.Domain.Service;
using SignUp.Infrastructure;
using SignUp.WebApi.ViewModels;
using SignUp.WebApi.ViewModels.System;

namespace SignUp.WebApi.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class SystemController : ControllerBase
    {
        private readonly ISystemDomainService _systemDomainService;

        public SystemController(ISystemDomainService systemDomainService)
        {
            _systemDomainService = systemDomainService;
        }
        #region 用户管理
        [HttpPost]
        public async Task<ActionResult> GetUserList(PageGridRequest req)
        {
            return new JsonResult(await _systemDomainService.GetUserList(req.PageIndex, req.PageSize, req.Wheres, req.Sort, req.Order));
        }
        /// <summary>
        /// 添加菜单
        /// </summary>
        /// <remarks>
        /// 描述:添加菜单
        /// </remarks>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        [UnitOfWork(typeof(SignUpDbContext))]
        public async Task<ActionResult> AddUser(AddUserRequest req)
        {
            return new JsonResult(await _systemDomainService.AddUser(req.UserName, req.Password, req.RealName, req.UserType));
        }
        /// <summary>
        /// 修改菜单
        /// </summary>
        /// <remarks>
        /// 描述:修改菜单
        /// </remarks>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPut]
        [UnitOfWork(typeof(SignUpDbContext))]
        public async Task<ActionResult> EditUser(EditUserRequest req)
        {
            return new JsonResult(await _systemDomainService.EditUser(req.Id, req.UserName, req.RealName, req.UserType));
        }
        /// <summary>
        /// 删除人员
        /// </summary>
        /// <remarks>
        /// 描述:删除人员
        /// </remarks>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete]
        [UnitOfWork(typeof(SignUpDbContext))]
        public async Task<ActionResult> DeleteUser(string id)
        {
            return new JsonResult(await _systemDomainService.DeleteUser(id));
        }
        /// <summary>
        /// 删除人员
        /// </summary>
        /// <remarks>
        /// 描述:删除人员
        /// </remarks>
        /// <param name="ids"></param>
        /// <returns></returns>
        [HttpDelete]
        [UnitOfWork(typeof(SignUpDbContext))]
        public ActionResult DeleteUserRange(string[] ids)
        {
            return new JsonResult(_systemDomainService.DeleteUserRange(ids));
        }
        #endregion
    }
}

删除仓储保存代码

        public async Task<SysUser> AddUser(string userName, string password, string realName, string userType)
        {
            SysUser model = SysUser.Add(userName, password, realName, userType);
            await _dbContext.SysUser.AddAsync(model);
            return model;
        }
学习交流

附笔者学习 .net core开发时参考相关项目实例源码:asp.net core webapi项目实例源代码锦集下载(72个)

评论列表
发表评论
+ 关注