mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-06-18 20:08:15 +08:00
- 增加 FreeSql.DbContext 实体对象的变化事件;
> 文档:https://github.com/2881099/FreeSql/wiki/DbContext#%E5%AE%9E%E4%BD%93%E5%8F%98%E5%8C%96%E4%BA%8B%E4%BB%B6 - 补充 Aop.CurdBefore 事件参数 Table 实体类型的元数据;
This commit is contained in:
@ -38,11 +38,20 @@ namespace FreeSql
|
||||
{
|
||||
_optionsPriv = new DbContextOptions();
|
||||
if (FreeSqlDbContextExtensions._dicSetDbContextOptions.TryGetValue(Orm, out var opt))
|
||||
{
|
||||
_optionsPriv.EnableAddOrUpdateNavigateList = opt.EnableAddOrUpdateNavigateList;
|
||||
_optionsPriv.OnEntityChange = opt.OnEntityChange;
|
||||
}
|
||||
}
|
||||
return _optionsPriv;
|
||||
}
|
||||
}
|
||||
internal void EmitOnEntityChange(List<DbContext.EntityChangeInfo> report)
|
||||
{
|
||||
var oec = UnitOfWork?.OnEntityChange ?? Options.OnEntityChange;
|
||||
if (oec == null || report == null || report.Any() == false) return;
|
||||
oec(report);
|
||||
}
|
||||
#endregion
|
||||
|
||||
protected DbContext()
|
||||
@ -146,20 +155,26 @@ namespace FreeSql
|
||||
#endregion
|
||||
|
||||
#region Queue Action
|
||||
internal List<EntityChangeInfo> _entityChangeReport = new List<EntityChangeInfo>();
|
||||
public class EntityChangeInfo
|
||||
{
|
||||
public object Object { get; set; }
|
||||
public EntityChangeType Type { get; set; }
|
||||
}
|
||||
public enum EntityChangeType { Insert, Update, Delete, SqlRaw }
|
||||
internal class ExecCommandInfo
|
||||
{
|
||||
public ExecCommandInfoType actionType { get; set; }
|
||||
public EntityChangeType changeType { get; set; }
|
||||
public IDbSet dbSet { get; set; }
|
||||
public Type stateType { get; set; }
|
||||
public Type entityType { get; set; }
|
||||
public object state { get; set; }
|
||||
}
|
||||
internal enum ExecCommandInfoType { Insert, Update, Delete }
|
||||
Queue<ExecCommandInfo> _actions = new Queue<ExecCommandInfo>();
|
||||
internal int _affrows = 0;
|
||||
|
||||
internal void EnqueueAction(ExecCommandInfoType actionType, IDbSet dbSet, Type stateType, Type entityType, object state) =>
|
||||
_actions.Enqueue(new ExecCommandInfo { actionType = actionType, dbSet = dbSet, stateType = stateType, entityType = entityType, state = state });
|
||||
internal void EnqueueAction(EntityChangeType changeType, IDbSet dbSet, Type stateType, Type entityType, object state) =>
|
||||
_actions.Enqueue(new ExecCommandInfo { changeType = changeType, dbSet = dbSet, stateType = stateType, entityType = entityType, state = state });
|
||||
#endregion
|
||||
|
||||
~DbContext() => this.Dispose();
|
||||
|
@ -13,10 +13,7 @@ namespace FreeSql
|
||||
async public virtual Task<int> SaveChangesAsync()
|
||||
{
|
||||
await ExecCommandAsync();
|
||||
UnitOfWork?.Commit();
|
||||
var ret = _affrows;
|
||||
_affrows = 0;
|
||||
return ret;
|
||||
return SaveChangesSuccess();
|
||||
}
|
||||
|
||||
static Dictionary<Type, Dictionary<string, Func<object, object[], Task<int>>>> _dicExecCommandDbContextBetchAsync = new Dictionary<Type, Dictionary<string, Func<object, object[], Task<int>>>>();
|
||||
@ -96,31 +93,31 @@ namespace FreeSql
|
||||
var isLiveUpdate = false;
|
||||
|
||||
if (_actions.Any() == false && states.Any() ||
|
||||
info != null && oldinfo.actionType != info.actionType ||
|
||||
info != null && oldinfo.changeType != info.changeType ||
|
||||
info != null && oldinfo.stateType != info.stateType ||
|
||||
info != null && oldinfo.entityType != info.entityType)
|
||||
{
|
||||
|
||||
if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType && oldinfo.entityType == info.entityType)
|
||||
if (info != null && oldinfo.changeType == info.changeType && oldinfo.stateType == info.stateType && oldinfo.entityType == info.entityType)
|
||||
{
|
||||
//最后一个,合起来发送
|
||||
states.Add(info.state);
|
||||
info = null;
|
||||
}
|
||||
|
||||
switch (oldinfo.actionType)
|
||||
switch (oldinfo.changeType)
|
||||
{
|
||||
case ExecCommandInfoType.Insert:
|
||||
case EntityChangeType.Insert:
|
||||
await funcInsert();
|
||||
break;
|
||||
case ExecCommandInfoType.Delete:
|
||||
case EntityChangeType.Delete:
|
||||
await funcDelete();
|
||||
break;
|
||||
}
|
||||
isLiveUpdate = true;
|
||||
}
|
||||
|
||||
if (isLiveUpdate || oldinfo.actionType == ExecCommandInfoType.Update)
|
||||
if (isLiveUpdate || oldinfo.changeType == EntityChangeType.Update)
|
||||
{
|
||||
if (states.Any())
|
||||
await funcUpdate(isLiveUpdate);
|
||||
|
@ -1,4 +1,8 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace FreeSql
|
||||
{
|
||||
public class DbContextOptions
|
||||
@ -17,5 +21,10 @@ namespace FreeSql
|
||||
/// - 属性集合不为空时,与数据库存在的关联数据(中间表)完全对比,计算出应该删除和添加的记录
|
||||
/// </summary>
|
||||
public bool EnableAddOrUpdateNavigateList { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 实体变化事件
|
||||
/// </summary>
|
||||
public Action<List<DbContext.EntityChangeInfo>> OnEntityChange { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -8,14 +8,26 @@ namespace FreeSql
|
||||
{
|
||||
partial class DbContext
|
||||
{
|
||||
|
||||
int SaveChangesSuccess()
|
||||
{
|
||||
UnitOfWork?.Commit();
|
||||
int ret;
|
||||
try
|
||||
{
|
||||
EmitOnEntityChange(_entityChangeReport);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_entityChangeReport.Clear();
|
||||
ret = _affrows;
|
||||
_affrows = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
public virtual int SaveChanges()
|
||||
{
|
||||
ExecCommand();
|
||||
UnitOfWork?.Commit();
|
||||
var ret = _affrows;
|
||||
_affrows = 0;
|
||||
return ret;
|
||||
return SaveChangesSuccess();
|
||||
}
|
||||
|
||||
static Dictionary<Type, Dictionary<string, Func<object, object[], int>>> _dicExecCommandDbContextBetch = new Dictionary<Type, Dictionary<string, Func<object, object[], int>>>();
|
||||
@ -96,31 +108,31 @@ namespace FreeSql
|
||||
var isLiveUpdate = false;
|
||||
|
||||
if (_actions.Any() == false && states.Any() ||
|
||||
info != null && oldinfo.actionType != info.actionType ||
|
||||
info != null && oldinfo.changeType != info.changeType ||
|
||||
info != null && oldinfo.stateType != info.stateType ||
|
||||
info != null && oldinfo.entityType != info.entityType)
|
||||
{
|
||||
|
||||
if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType && oldinfo.entityType == info.entityType)
|
||||
if (info != null && oldinfo.changeType == info.changeType && oldinfo.stateType == info.stateType && oldinfo.entityType == info.entityType)
|
||||
{
|
||||
//最后一个,合起来发送
|
||||
states.Add(info.state);
|
||||
info = null;
|
||||
}
|
||||
|
||||
switch (oldinfo.actionType)
|
||||
switch (oldinfo.changeType)
|
||||
{
|
||||
case ExecCommandInfoType.Insert:
|
||||
case EntityChangeType.Insert:
|
||||
funcInsert();
|
||||
break;
|
||||
case ExecCommandInfoType.Delete:
|
||||
case EntityChangeType.Delete:
|
||||
funcDelete();
|
||||
break;
|
||||
}
|
||||
isLiveUpdate = true;
|
||||
}
|
||||
|
||||
if (isLiveUpdate || oldinfo.actionType == ExecCommandInfoType.Update)
|
||||
if (isLiveUpdate || oldinfo.changeType == EntityChangeType.Update)
|
||||
{
|
||||
if (states.Any())
|
||||
funcUpdate(isLiveUpdate);
|
||||
|
Reference in New Issue
Block a user