本文介绍了如何在ASP.NETCore项目中使用EntityFrameworkCore(EFCore)进行事务管理,包括手动创建事务接口、UnitOfWork实现、全局事务过滤器的应用以及事务开关的使用,以减少代码冗余并控制事务开销。
摘要生成于
,由 DeepSeek-R1 满血版支持,
平常项目中设计到数据库操作的时候一般情况是不会有问题的,但是当一个控制器中设计到多处具有对数据库的操作时,比如一个接口中涉及到修改信息,然后删除原本信息,分配新的权限三个操作,如果运行到一半数据库突然出现故障后,导致后面还有的操作没有进行,就会到处信息出现问题.
当然EF Core提供的
SaveChanges
方法本身是支持事务的,如果多个操作,其中任何一个操作失败了,都会触发事务回滚,保证所有操作都不会生效。
但在我们实际业务中,业务往往都是比较复杂的,默认事务无法满足我们的需求,这时候我们就需要手动控制事务,
在EF提供的事务API有:
开始、提交和回滚事务。
具体实现方式如下:
一. 事务基本使用
1. 建立事务会用到的接口方法
public interface IUnitOfWork
/// <summary>
/// 开始事务
/// </summary>
void BeginTransaction();
/// <summary>
/// 提交事务
/// </summary>
void CommitTransaction();
2. 实现接口
public class UnitOfWork : IUnitOfWork, IDisposable
private readonly ApplicationDbContext _dbContext;
/// <summary>
/// 事务
/// </summary>
private IDbContextTransaction? _transaction;
/// <summary>
/// 是否提交
/// </summary>
private bool _isCommit = false;
public UnitOfWork(ApplicationDbContext dbContext)
_dbContext = dbContext;
/// <summary>
/// 开启事务
/// </summary>
/// <exception cref="NotImplementedException"></exception>
public void BeginTransaction()
_transaction = _dbContext.Database.BeginTransaction();
/// <summary>
/// 提交事务
/// </summary>
/// <exception cref="NotImplementedException"></exception>
public void CommitTransaction()
if (_transaction != null)
_transaction.Commit();
_isCommit = true;
/// <summary>
/// 回滚事务
/// </summary>
/// <exception cref="NotImplementedException"></exception>
public void Dispose()
// 未提交事务,回滚
if (_transaction != null && !_isCommit)
_transaction.Rollback();
// 提交过的事务,释放资源
if(_transaction != null)
_transaction.Dispose();
3. 在Program.cs中注入服务
builder.Services.AddScoped<IUnitOfWork, UnitOfWork>();
4. 实现事务操作
// 开启事务
_unitOfWork.BeginTransaction();
业务逻辑,设计数据库的一些操作
//提交事务
_unitOfWork.CommitTransaction();
catch
responseResult.SetError("服务器异常");
return BadRequest(responseResult);
二. 事务步骤优化
按照前面的步骤我们在需要使用事务的地方都需要手动添加事务的开启以及提交.如果项目很庞大的话工作量岂不是很大,而且也会造成代码大量重复.
所以我们可以通过自定义WebApi的行为过滤器,来实现在Action执行前与执行后,控制事务开启与提交。
具体实现如下:
1. 添加过滤器
public class UnitOfWorkFilterAttribute : ActionFilterAttribute
/// <summary>
/// 在Action执行前判断是否开启事务
/// </summary>
/// <param name="context"></param>
public override void OnActionExecuting(ActionExecutingContext context)
var _unitOfWork = context.HttpContext.RequestServices.GetService<IUnitOfWork>();
// 开启事务
_unitOfWork.BeginTransaction();
/// <summary>
/// 在Action执行后判断是否需要提交事务
/// </summary>
/// <param name="context"></param>
public override void OnActionExecuted(ActionExecutedContext context)
var _unitOfWork = context.HttpContext.RequestServices.GetService<IUnitOfWork>();
// 提交事务
_unitOfWork.CommitTransaction();
2. 为所有接口添加全局过滤器
实现了过滤器的功能,我们可以通过给api添加表示的方式为api添加过滤器
为了方便我们选择给所有控制器添加都添加该标识
builder.Services.AddControllers(
configure =>
configure.Filters.Add<UnitOfWorkFilterAttribute>();
这样所有的api都添加上了UnitOfWorkFilterAttribute,但是这样做有着很明显的缺陷就是会增加事务的开销,即使是简单的一个Select查询语句都会被加上事务,所以我们可以创建一个事务的开关.
3. 为事务添加开关
public class UnitOfWorkAttribute : Attribute
/// <summary>
/// 是否开启事务
/// </summary>
public bool IsTransactional { get; set; } = true;
此时我们修改之前的过滤器配置,添加开关判断语句
我们可以在不需要事务的地方添加上图注释.我们从操作方法的元数据中获取UnitOfWorkAttribute
类型的属性,判断IsTransactional的值是否为false,为false时就不开启事务
自此,事务的基本使用就告捷啦
Entity Framework (EF) Core 是轻量化、可扩展、开源和跨平台版的常用 Entity Framework 数据访问技术。
EF Core 可用作对象关系映射程序 (O/RM),以便于 .NET 开发人员能够使用 .NET 对象来处理数据库,这样就不必经常编写大部分数据访问代码了。
说简单点,就是在我们做增删改查的时候,不用再写非常繁琐的SQL语句,
写完SQL语句后,查询出来的数据还要手
1.ORM:Object Relation Mapping. 让开发者用对象操作的形式操作关系数据库.
比如插入:
User user = new User(){Name="admin",Password="123"};
orm.Save(User);
比如查询:
Book b = orm.Book.Single(b=>b.Id==3||b.Name.Contains(".NET"));
string bookName = b.Name;
安装nugut包
Microsoft.EntityFrameworkCore.SqlServer
连接对应数据库的package,本次是连接sqlserver数据库
Microsoft.EntityFrameworkCore.Tools
用于实体与数据库的相互映射
CodeFirst(基础版)
新建上下文类(继承于DbContext)
1.生成空构造函数
此处我们一般用不到,但是必须写
/// <summary>
/// 必须要有空构造函数,不然不能执行
(3)Microsoft.EntityFrameworkCore.Tools
(4)MySql.Data.EntityFrameworkCore (这里以MySql为例)
(5)My...
官网:https://docs.microsoft.com/zh-cn/aspnet/core/data/ef-mvc/intro?view=aspnetcore-2.2#register-the-schoolcontext
脚手架生成Model,DbContext:https://docs.microsoft.com/zh-cn/ef/core/get-started/aspnetcore/...