mirror of
https://github.com/dotnetcore/FreeSql.git
synced 2026-02-03 15:00:53 +08:00
Page:
Unit of Work
Pages
ADO
AOP
API
BaseEntity
Cascade Deletion
Cascade Saving
CodeFirst
DI UnitOfWorkManager
Dapper比较
DbContext
DbFirst
Delete Data
Dynamic Operations
Entity Relationship
EntityFramework比较
FluentApi
Getting Started
Greed Loading
Group Aggregation Query
Home
Import Entity Configuration from Database
Insert Data
Insert or Update
Install
Lazy Loading
Linq to Sql
LinqToSql
Nested Query
Pagination
Parent Child Relationship Query
Query Data
Query from Multi Tables
Query from Single Table
Repository Layer
Repository
Return Data
Unit of Work
Update Data
With Sql
withsql
事务
修改
入门
分组聚合查询
分表分库
分页查询
删除
动态操作
单表查询
多表查询
安装
实体关系
实体特性
导入数据库特性
嵌套查询
工作单元
常见问题
延时加载
性能
支持我们
更新日志
查询
查询父子关系
添加
添加或修改
租户
类型映射
联合查询
联级保存
联级删除
聚合根(实验室)
自定义特性
表达式函数
读写分离
贪婪加载
过滤器
返回数据
首页
骚操作
Clone
9
Unit of Work
2881099 edited this page 2025-12-16 09:57:09 +08:00
Table of Contents
中文 | 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();
Usage
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();
}
External Transaction
// Scenario: An open Connection and Transaction already exist
using (var conn = new SqlConnection("..."))
{
conn.Open();
using (var tran = conn.BeginTransaction())
{
// 1. Native/Dapper operation
// command.Transaction = tran;
// command.ExecuteNonQuery();
// 2. Bridging to FreeSql
// Create an adapter using extension methods, passing in the existing tran
using (var uow = fsql.CreateUnitOfWork(tran))
{
// Repositories or Orms obtained under this uow will use the passed-in tran
var repo = uow.GetRepository<MyEntity>();
repo.Insert(new MyEntity { Name = "FreeSql Insert" });
// Or directly use Orm
uow.Orm.Insert(new MyEntity { Name = "Direct Orm Insert" }).ExecuteAffrows();
// The Commit here only triggers FreeSql events, it does not commit the physical transaction
uow.Commit();
}
// 3. The actual commit is controlled by the outermost layer
tran.Commit();
}
}
Interface Definition
The uow.GetOrBeginTransaction() method can get the transaction object.
public interface IUnitOfWork : IDisposable
{
/// <summary>
/// The object Select/Delete/Insert/Update/InsertOrUpdate is consistent with the unit of work transaction and can be omitted to pass WithTransaction
/// </summary>
IFreeSql Orm { get; }
/// <summary>
/// Open the transaction, or return to the opened transaction
/// </summary>
/// <param name="isCreate">If the transaction is not opened, then open</param>
/// <returns></returns>
DbTransaction GetOrBeginTransaction(bool isCreate = true);
IsolationLevel? IsolationLevel { get; set; }
void Commit();
void Rollback();
/// <summary>
/// Entity change tracking within the unit of work
/// </summary>
DbContext.EntityChangeReport EntityChangeReport { get; }
}
Entity Changing Event
Global Settings:
fsql.SetDbContextOptions(opt => {
opt.OnEntityChange = report => {
Console.WriteLine(report);
};
});
Individual Settings:
var uow = fsql.CreateUnitOfWork();
uow.OnEntityChange = report => {
Console.WriteLine(report);
};
The parameter report is a list collection, and the type of the collection elements is defined as follows:
public class ChangeInfo {
public object Object { get; set; }
public EntityChangeType Type { get; set; }
/// <summary>
/// When Type = Update, get the object before the update
/// </summary>
public object BeforeObject { get; set; }
}
public enum EntityChangeType { Insert, Update, Delete, SqlRaw }
| Type of Change | Description |
|---|---|
| Insert | The entity object is inserted |
| Update | The entity object is updated |
| Delete | The entity object is deleted |
| SqlRaw | SQL statement executed |
SqlRaw currently has two special features:
- When the navigation properties are updated in the many-to-many cascade, delete the relevant data in the intermediate table.
- The common repository
BaseRepositoryhas a Delete method, and the parameter is an expression, not an entity.
int Delete(Expression<Func<TEntity, bool>> predicate);
DbContext.SaveChanges or Repository's Insert/Update/Delete method of the entity, or UnitOfWork.Commit operation will trigger this event at most once.
Reference
Basic
- 入门 Getting Started
- 安装 How to Install
- 添加 Insert Data
- 删除 Delete Data
- 修改 Update Data
- 添加或修改 Insert or Update ✨
- 查询 Query Data
- 仓储层 Repository Layer
- CodeFirst
- DbFirst
- 表达式函数
- 事务
- 过滤器
- ADO
- AOP✨
- 读写分离
- 分表分库
- 租户
- 性能
- 动态操作 Dynamic Operations
- 你不知道的功能✨
- API参考