-
Notifications
You must be signed in to change notification settings - Fork 857
Unit of Work
2881099 edited this page Nov 22, 2023
·
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>
/// 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; }
}
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
BaseRepository
has 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.