- Notifications
You must be signed in to change notification settings - Fork 889
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.