-
Notifications
You must be signed in to change notification settings - Fork 892
Unit of Work
AlexLEWIS edited this page Sep 8, 2021
·
7 revisions
中文 | English
Unit of work can put multiple repositories into one unit for internal management and execution, and finally execute all operations through Commit. Unit of work internally uses database transactions.
static IFreeSql fsql = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.MySql, connectionString)
//Automatically synchronize the entity structure to the database.
.UseAutoSyncStructure(true)
//Be sure to define as singleton mode
.Build(); using (var uow = fsql.CreateUnitOfWork())
{
var songRepo = fsql.GetRepository<Song>();
var userRepo = fsql.GetRepository<User>();
songRepo.UnitOfWork = uow; //Manually bind unit of work
userRepo.UnitOfWork = uow;
songRepo.Insert(new Song());
userRepo.Update(...);
uow.Orm.Insert(new Song()).ExecuteAffrows();
//Note: uow.Orm and fsql are both IFreeSql
//uow.Orm CRUD and uow are the same transaction (understood as temporary IFreeSql)
//fsql CRUD and uow are not in the same transaction
uow.Commit();
}The uow.GetOrBeginTransaction() method can get the transaction object.
public interface IUnitOfWork : IDisposable
{
/// <summary>
/// 该对象 Select/Delete/Insert/Update/InsertOrUpdate 与工作单元事务保持一致,可省略传递 WithTransaction
/// </summary>
IFreeSql Orm { get; }
/// <summary>
/// 开启事务,或者返回已开启的事务
/// </summary>
/// <param name="isCreate">若未开启事务,则开启</param>
/// <returns></returns>
DbTransaction GetOrBeginTransaction(bool isCreate = true);
IsolationLevel? IsolationLevel { get; set; }
void Commit();
void Rollback();
/// <summary>
/// 工作单元内的实体变化跟踪
/// </summary>
DbContext.EntityChangeReport EntityChangeReport { get; }
}全局设置:
fsql.SetDbContextOptions(opt => {
opt.OnEntityChange = report => {
Console.WriteLine(report);
};
});单独设置:
var uow = fsql.CreateUnitOfWork();
uow.OnEntityChange = report => {
Console.WriteLine(report);
};参数 report 是一个 List 集合,集合元素的类型定义如下:
public class ChangeInfo {
public object Object { get; set; }
public EntityChangeType Type { get; set; }
/// <summary>
/// Type = Update 的时候,获取更新之前的对象
/// </summary>
public object BeforeObject { get; set; }
}
public enum EntityChangeType { Insert, Update, Delete, SqlRaw }| 变化类型 | 说明 |
|---|---|
| Insert | 实体对象被插入 |
| Update | 实体对象被更新 |
| Delete | 实体对象被删除 |
| SqlRaw | 执行了SQL语句 |
SqlRaw 目前有两处地方比较特殊:
- 多对多联级更新导航属性的时候,对中间表的全部删除操作;
- 通用仓储类 BaseRepository 有一个 Delete 方法,参数为表达式,而并非实体;
int Delete(Expression<Func<TEntity, bool>> predicate);DbContext.SaveChanges,或者 Repository 对实体的 Insert/Update/Delete,或者 UnitOfWork.Commit 操作都会最多触发一次该事件。