mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
AggregateRootRepository
This commit is contained in:
parent
2b8ec5c570
commit
df18373ee5
@ -57,11 +57,11 @@ namespace FreeSql
|
|||||||
public Type EntityType => _repository.EntityType;
|
public Type EntityType => _repository.EntityType;
|
||||||
public IDataFilter<TEntity> DataFilter => _repository.DataFilter;
|
public IDataFilter<TEntity> DataFilter => _repository.DataFilter;
|
||||||
|
|
||||||
public void Attach(TEntity entity) => AttachCascade(entity);
|
public void Attach(TEntity entity) => AttachAggregateRoot(entity);
|
||||||
public void Attach(IEnumerable<TEntity> entity)
|
public void Attach(IEnumerable<TEntity> entity)
|
||||||
{
|
{
|
||||||
foreach (var item in entity)
|
foreach (var item in entity)
|
||||||
AttachCascade(item);
|
AttachAggregateRoot(item);
|
||||||
}
|
}
|
||||||
public IBaseRepository<TEntity> AttachOnlyPrimary(TEntity data) => _repository.AttachOnlyPrimary(data);
|
public IBaseRepository<TEntity> AttachOnlyPrimary(TEntity data) => _repository.AttachOnlyPrimary(data);
|
||||||
public Dictionary<string, object[]> CompareState(TEntity newdata) => _repository.CompareState(newdata);
|
public Dictionary<string, object[]> CompareState(TEntity newdata) => _repository.CompareState(newdata);
|
||||||
@ -120,7 +120,7 @@ namespace FreeSql
|
|||||||
if (data == null) throw new ArgumentNullException(nameof(data));
|
if (data == null) throw new ArgumentNullException(nameof(data));
|
||||||
var key = Orm.GetEntityKeyString(EntityType, data, false);
|
var key = Orm.GetEntityKeyString(EntityType, data, false);
|
||||||
var state = new EntityState((TEntity)EntityType.CreateInstanceGetDefaultValue(), key);
|
var state = new EntityState((TEntity)EntityType.CreateInstanceGetDefaultValue(), key);
|
||||||
AggregateRootUtils.MapEntityValueCascade(Orm, EntityType, data, state.Value);
|
AggregateRootUtils.MapEntityValue(Orm, EntityType, data, state.Value);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
bool? ExistsInStates(object data)
|
bool? ExistsInStates(object data)
|
||||||
@ -130,7 +130,7 @@ namespace FreeSql
|
|||||||
if (string.IsNullOrEmpty(key)) return null;
|
if (string.IsNullOrEmpty(key)) return null;
|
||||||
return _states.ContainsKey(key);
|
return _states.ContainsKey(key);
|
||||||
}
|
}
|
||||||
void AttachCascade(TEntity entity)
|
void AttachAggregateRoot(TEntity entity)
|
||||||
{
|
{
|
||||||
var state = CreateEntityState(entity);
|
var state = CreateEntityState(entity);
|
||||||
if (_states.ContainsKey(state.Key)) _states[state.Key] = state;
|
if (_states.ContainsKey(state.Key)) _states[state.Key] = state;
|
||||||
@ -138,17 +138,18 @@ namespace FreeSql
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Select
|
#region Selectoriginal
|
||||||
public virtual ISelect<TEntity> Select
|
public virtual ISelect<TEntity> Select => SelectAggregateRoot;
|
||||||
|
ISelect<TEntity> SelectAggregateRoot
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var query = _repository.Select.TrackToList(SelectTrackingAggregateRootNavigate);
|
var query = _repository.Select.TrackToList(SelectAggregateRootTracking);
|
||||||
SelectFetchAggregateRootNavigate(query, EntityType, "", new Stack<Type>());
|
SelectAggregateRootNavigateReader(query, EntityType, "", new Stack<Type>());
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void SelectFetchAggregateRootNavigate<T1>(ISelect<T1> currentQuery, Type entityType, string navigatePath, Stack<Type> ignores)
|
void SelectAggregateRootNavigateReader<T1>(ISelect<T1> currentQuery, Type entityType, string navigatePath, Stack<Type> ignores)
|
||||||
{
|
{
|
||||||
if (ignores.Any(a => a == entityType)) return;
|
if (ignores.Any(a => a == entityType)) return;
|
||||||
ignores.Push(entityType);
|
ignores.Push(entityType);
|
||||||
@ -164,12 +165,12 @@ namespace FreeSql
|
|||||||
case TableRefType.OneToOne:
|
case TableRefType.OneToOne:
|
||||||
if (ignores.Any(a => a == tbref.RefEntityType)) break;
|
if (ignores.Any(a => a == tbref.RefEntityType)) break;
|
||||||
currentQuery.IncludeByPropertyName(navigateExpression);
|
currentQuery.IncludeByPropertyName(navigateExpression);
|
||||||
SelectFetchAggregateRootNavigate(currentQuery, tbref.RefEntityType, navigateExpression, ignores);
|
SelectAggregateRootNavigateReader(currentQuery, tbref.RefEntityType, navigateExpression, ignores);
|
||||||
break;
|
break;
|
||||||
case TableRefType.OneToMany:
|
case TableRefType.OneToMany:
|
||||||
var ignoresCopy = new Stack<Type>(ignores.ToArray());
|
var ignoresCopy = new Stack<Type>(ignores.ToArray());
|
||||||
currentQuery.IncludeByPropertyName(navigateExpression, then =>
|
currentQuery.IncludeByPropertyName(navigateExpression, then =>
|
||||||
SelectFetchAggregateRootNavigate(then, tbref.RefEntityType, "", ignoresCopy));
|
SelectAggregateRootNavigateReader(then, tbref.RefEntityType, "", ignoresCopy));
|
||||||
break;
|
break;
|
||||||
case TableRefType.ManyToMany:
|
case TableRefType.ManyToMany:
|
||||||
currentQuery.IncludeByPropertyName(navigateExpression);
|
currentQuery.IncludeByPropertyName(navigateExpression);
|
||||||
@ -181,7 +182,7 @@ namespace FreeSql
|
|||||||
}
|
}
|
||||||
ignores.Pop();
|
ignores.Pop();
|
||||||
}
|
}
|
||||||
void SelectTrackingAggregateRootNavigate(object list)
|
void SelectAggregateRootTracking(object list)
|
||||||
{
|
{
|
||||||
if (list == null) return;
|
if (list == null) return;
|
||||||
var ls = list as IEnumerable<TEntity>;
|
var ls = list as IEnumerable<TEntity>;
|
||||||
@ -202,7 +203,7 @@ namespace FreeSql
|
|||||||
if (Orm.CodeFirst.GetTableByEntity(itemType)?.Primarys.Any() != true) return;
|
if (Orm.CodeFirst.GetTableByEntity(itemType)?.Primarys.Any() != true) return;
|
||||||
if (itemType.GetConstructor(Type.EmptyTypes) == null) return;
|
if (itemType.GetConstructor(Type.EmptyTypes) == null) return;
|
||||||
}
|
}
|
||||||
AttachCascade(item as TEntity);
|
AttachAggregateRoot(item as TEntity);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -15,28 +15,28 @@ namespace FreeSql
|
|||||||
{
|
{
|
||||||
partial class AggregateRootRepository<TEntity>
|
partial class AggregateRootRepository<TEntity>
|
||||||
{
|
{
|
||||||
public TEntity Insert(TEntity entity) => InsertCascade(new[] { entity }).FirstOrDefault();
|
public TEntity Insert(TEntity entity) => InsertAggregateRoot(new[] { entity }).FirstOrDefault();
|
||||||
public List<TEntity> Insert(IEnumerable<TEntity> entitys) => InsertCascade(entitys);
|
public List<TEntity> Insert(IEnumerable<TEntity> entitys) => InsertAggregateRoot(entitys);
|
||||||
public TEntity InsertOrUpdate(TEntity entity) => InsertOrUpdateCascade(entity);
|
public TEntity InsertOrUpdate(TEntity entity) => InsertOrUpdateAggregateRoot(entity);
|
||||||
public int Update(TEntity entity) => UpdateCascade(new[] { entity });
|
public int Update(TEntity entity) => UpdateAggregateRoot(new[] { entity });
|
||||||
public int Update(IEnumerable<TEntity> entitys) => UpdateCascade(entitys);
|
public int Update(IEnumerable<TEntity> entitys) => UpdateAggregateRoot(entitys);
|
||||||
public int Delete(TEntity entity) => DeleteCascade(new[] { entity });
|
public int Delete(TEntity entity) => DeleteAggregateRoot(new[] { entity });
|
||||||
public int Delete(IEnumerable<TEntity> entitys) => DeleteCascade(entitys);
|
public int Delete(IEnumerable<TEntity> entitys) => DeleteAggregateRoot(entitys);
|
||||||
public int Delete(Expression<Func<TEntity, bool>> predicate) => DeleteCascade(Where(predicate).ToList());
|
public int Delete(Expression<Func<TEntity, bool>> predicate) => DeleteAggregateRoot(SelectAggregateRoot.Where(predicate).ToList());
|
||||||
public List<object> DeleteCascadeByDatabase(Expression<Func<TEntity, bool>> predicate)
|
public List<object> DeleteCascadeByDatabase(Expression<Func<TEntity, bool>> predicate)
|
||||||
{
|
{
|
||||||
var deletedOutput = new List<object>();
|
var deletedOutput = new List<object>();
|
||||||
DeleteCascade(Where(predicate).ToList(), deletedOutput);
|
DeleteAggregateRoot(SelectAggregateRoot.Where(predicate).ToList(), deletedOutput);
|
||||||
return deletedOutput;
|
return deletedOutput;
|
||||||
}
|
}
|
||||||
public void SaveMany(TEntity entity, string propertyName) => SaveManyCascade(entity, propertyName);
|
public void SaveMany(TEntity entity, string propertyName) => SaveManyAggregateRoot(entity, propertyName);
|
||||||
|
|
||||||
protected virtual List<TEntity> InsertCascade(IEnumerable<TEntity> entitys)
|
protected virtual List<TEntity> InsertAggregateRoot(IEnumerable<TEntity> entitys)
|
||||||
{
|
{
|
||||||
var repos = new Dictionary<Type, object>();
|
var repos = new Dictionary<Type, object>();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return InsertCascadeStatic(_repository, GetChildRepository, entitys);
|
return InsertAggregateRootStatic(_repository, GetChildRepository, entitys);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -44,12 +44,12 @@ namespace FreeSql
|
|||||||
_repository.FlushState();
|
_repository.FlushState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected static List<TEntity> InsertCascadeStatic(IBaseRepository<TEntity> rootRepository, Func<Type, IBaseRepository<object>> getChildRepository, IEnumerable<TEntity> rootEntitys) {
|
protected static List<TEntity> InsertAggregateRootStatic(IBaseRepository<TEntity> rootRepository, Func<Type, IBaseRepository<object>> getChildRepository, IEnumerable<TEntity> rootEntitys) {
|
||||||
Dictionary<Type, Dictionary<string, bool>> ignores = new Dictionary<Type, Dictionary<string, bool>>();
|
Dictionary<Type, Dictionary<string, bool>> ignores = new Dictionary<Type, Dictionary<string, bool>>();
|
||||||
Dictionary<Type, IBaseRepository<object>> repos = new Dictionary<Type, IBaseRepository<object>>();
|
Dictionary<Type, IBaseRepository<object>> repos = new Dictionary<Type, IBaseRepository<object>>();
|
||||||
return LocalInsertCascade(rootRepository, rootEntitys);
|
return LocalInsertAggregateRoot(rootRepository, rootEntitys);
|
||||||
|
|
||||||
bool LocalCanCascade(Type entityType, object entity, bool isadd)
|
bool LocalCanAggregateRoot(Type entityType, object entity, bool isadd)
|
||||||
{
|
{
|
||||||
var stateKey = rootRepository.Orm.GetEntityKeyString(entityType, entity, false);
|
var stateKey = rootRepository.Orm.GetEntityKeyString(entityType, entity, false);
|
||||||
if (stateKey == null) return true;
|
if (stateKey == null) return true;
|
||||||
@ -69,10 +69,10 @@ namespace FreeSql
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
List<T1> LocalInsertCascade<T1>(IBaseRepository<T1> repository, IEnumerable<T1> entitys) where T1 : class
|
List<T1> LocalInsertAggregateRoot<T1>(IBaseRepository<T1> repository, IEnumerable<T1> entitys) where T1 : class
|
||||||
{
|
{
|
||||||
var ret = repository.Insert(entitys);
|
var ret = repository.Insert(entitys);
|
||||||
foreach (var entity in entitys) LocalCanCascade(repository.EntityType, entity, true);
|
foreach (var entity in entitys) LocalCanAggregateRoot(repository.EntityType, entity, true);
|
||||||
|
|
||||||
var table = repository.Orm.CodeFirst.GetTableByEntity(repository.EntityType);
|
var table = repository.Orm.CodeFirst.GetTableByEntity(repository.EntityType);
|
||||||
foreach (var prop in table.Properties.Values)
|
foreach (var prop in table.Properties.Values)
|
||||||
@ -85,14 +85,14 @@ namespace FreeSql
|
|||||||
var otoList = ret.Select(entity =>
|
var otoList = ret.Select(entity =>
|
||||||
{
|
{
|
||||||
var otoItem = table.GetPropertyValue(entity, prop.Name);
|
var otoItem = table.GetPropertyValue(entity, prop.Name);
|
||||||
if (LocalCanCascade(tbref.RefEntityType, otoItem, false) == false) return null;
|
if (LocalCanAggregateRoot(tbref.RefEntityType, otoItem, false) == false) return null;
|
||||||
AggregateRootUtils.SetNavigateRelationshipValue(repository.Orm, tbref, table.Type, entity, otoItem);
|
AggregateRootUtils.SetNavigateRelationshipValue(repository.Orm, tbref, table.Type, entity, otoItem);
|
||||||
return otoItem;
|
return otoItem;
|
||||||
}).Where(entity => entity != null).ToArray();
|
}).Where(entity => entity != null).ToArray();
|
||||||
if (otoList.Any())
|
if (otoList.Any())
|
||||||
{
|
{
|
||||||
var repo = getChildRepository(tbref.RefEntityType);
|
var repo = getChildRepository(tbref.RefEntityType);
|
||||||
LocalInsertCascade(repo, otoList);
|
LocalInsertAggregateRoot(repo, otoList);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TableRefType.OneToMany:
|
case TableRefType.OneToMany:
|
||||||
@ -103,7 +103,7 @@ namespace FreeSql
|
|||||||
var otmItems = new List<object>();
|
var otmItems = new List<object>();
|
||||||
foreach (var otmItem in otmEach)
|
foreach (var otmItem in otmEach)
|
||||||
{
|
{
|
||||||
if (LocalCanCascade(tbref.RefEntityType, otmItem, false) == false) continue;
|
if (LocalCanAggregateRoot(tbref.RefEntityType, otmItem, false) == false) continue;
|
||||||
otmItems.Add(otmItem);
|
otmItems.Add(otmItem);
|
||||||
}
|
}
|
||||||
AggregateRootUtils.SetNavigateRelationshipValue(repository.Orm, tbref, table.Type, entity, otmItems);
|
AggregateRootUtils.SetNavigateRelationshipValue(repository.Orm, tbref, table.Type, entity, otmItems);
|
||||||
@ -112,7 +112,7 @@ namespace FreeSql
|
|||||||
if (otmList.Any())
|
if (otmList.Any())
|
||||||
{
|
{
|
||||||
var repo = getChildRepository(tbref.RefEntityType);
|
var repo = getChildRepository(tbref.RefEntityType);
|
||||||
LocalInsertCascade(repo, otmList);
|
LocalInsertAggregateRoot(repo, otmList);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TableRefType.ManyToMany:
|
case TableRefType.ManyToMany:
|
||||||
@ -125,7 +125,7 @@ namespace FreeSql
|
|||||||
if (mtmMidList.Any())
|
if (mtmMidList.Any())
|
||||||
{
|
{
|
||||||
var repo = getChildRepository(tbref.RefMiddleEntityType);
|
var repo = getChildRepository(tbref.RefMiddleEntityType);
|
||||||
LocalInsertCascade(repo, mtmMidList);
|
LocalInsertAggregateRoot(repo, mtmMidList);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TableRefType.PgArrayToMany:
|
case TableRefType.PgArrayToMany:
|
||||||
@ -136,7 +136,7 @@ namespace FreeSql
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual TEntity InsertOrUpdateCascade(TEntity entity)
|
protected virtual TEntity InsertOrUpdateAggregateRoot(TEntity entity)
|
||||||
{
|
{
|
||||||
var stateKey = Orm.GetEntityKeyString(EntityType, entity, false);
|
var stateKey = Orm.GetEntityKeyString(EntityType, entity, false);
|
||||||
if (entity == null) throw new ArgumentNullException(nameof(entity));
|
if (entity == null) throw new ArgumentNullException(nameof(entity));
|
||||||
@ -150,13 +150,13 @@ namespace FreeSql
|
|||||||
}
|
}
|
||||||
if (flagExists == true)
|
if (flagExists == true)
|
||||||
{
|
{
|
||||||
var affrows = UpdateCascade(new[] { entity });
|
var affrows = UpdateAggregateRoot(new[] { entity });
|
||||||
if (affrows > 0) return entity;
|
if (affrows > 0) return entity;
|
||||||
}
|
}
|
||||||
Orm.ClearEntityPrimaryValueWithIdentity(EntityType, entity);
|
Orm.ClearEntityPrimaryValueWithIdentity(EntityType, entity);
|
||||||
return InsertCascade(new[] { entity }).FirstOrDefault();
|
return InsertAggregateRoot(new[] { entity }).FirstOrDefault();
|
||||||
}
|
}
|
||||||
protected virtual int UpdateCascade(IEnumerable<TEntity> entitys)
|
protected virtual int UpdateAggregateRoot(IEnumerable<TEntity> entitys)
|
||||||
{
|
{
|
||||||
List<NativeTuple<Type, object>> insertLog = new List<NativeTuple<Type, object>>();
|
List<NativeTuple<Type, object>> insertLog = new List<NativeTuple<Type, object>>();
|
||||||
List<NativeTuple<Type, object, object, List<string>>> updateLog = new List<NativeTuple<Type, object, object, List<string>>>();
|
List<NativeTuple<Type, object, object, List<string>>> updateLog = new List<NativeTuple<Type, object, object, List<string>>>();
|
||||||
@ -165,12 +165,12 @@ namespace FreeSql
|
|||||||
{
|
{
|
||||||
var stateKey = Orm.GetEntityKeyString(EntityType, entity, false);
|
var stateKey = Orm.GetEntityKeyString(EntityType, entity, false);
|
||||||
if (_states.TryGetValue(stateKey, out var state) == false) throw new Exception($"AggregateRootRepository 使用仓储对象查询后,才可以更新数据 {Orm.GetEntityString(EntityType, entity)}");
|
if (_states.TryGetValue(stateKey, out var state) == false) throw new Exception($"AggregateRootRepository 使用仓储对象查询后,才可以更新数据 {Orm.GetEntityString(EntityType, entity)}");
|
||||||
AggregateRootUtils.CompareEntityValueCascade(Orm, EntityType, state.Value, entity, null, insertLog, updateLog, deleteLog);
|
AggregateRootUtils.CompareEntityValue(Orm, EntityType, state.Value, entity, null, insertLog, updateLog, deleteLog);
|
||||||
AttachCascade(entity);
|
AttachAggregateRoot(entity);
|
||||||
}
|
}
|
||||||
return insertLog.Count + updateLog.Count + deleteLog.Count;
|
return insertLog.Count + updateLog.Count + deleteLog.Count;
|
||||||
}
|
}
|
||||||
protected virtual int DeleteCascade(IEnumerable<TEntity> entitys, List<object> deletedOutput = null)
|
protected virtual int DeleteAggregateRoot(IEnumerable<TEntity> entitys, List<object> deletedOutput = null)
|
||||||
{
|
{
|
||||||
List<NativeTuple<Type, object>> insertLog = new List<NativeTuple<Type, object>>();
|
List<NativeTuple<Type, object>> insertLog = new List<NativeTuple<Type, object>>();
|
||||||
List<NativeTuple<Type, object, object, List<string>>> updateLog = new List<NativeTuple<Type, object, object, List<string>>>();
|
List<NativeTuple<Type, object, object, List<string>>> updateLog = new List<NativeTuple<Type, object, object, List<string>>>();
|
||||||
@ -178,22 +178,22 @@ namespace FreeSql
|
|||||||
foreach (var entity in entitys)
|
foreach (var entity in entitys)
|
||||||
{
|
{
|
||||||
var stateKey = Orm.GetEntityKeyString(EntityType, entity, false);
|
var stateKey = Orm.GetEntityKeyString(EntityType, entity, false);
|
||||||
AggregateRootUtils.CompareEntityValueCascade(Orm, EntityType, entity, null, null, insertLog, updateLog, deleteLog);
|
AggregateRootUtils.CompareEntityValue(Orm, EntityType, entity, null, null, insertLog, updateLog, deleteLog);
|
||||||
_states.Remove(stateKey);
|
_states.Remove(stateKey);
|
||||||
}
|
}
|
||||||
if (deletedOutput != null) deletedOutput.AddRange(deleteLog.Select(a => a.Item2));
|
if (deletedOutput != null) deletedOutput.AddRange(deleteLog.Select(a => a.Item2));
|
||||||
return deleteLog.Count;
|
return deleteLog.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void SaveManyCascade(TEntity entity, string propertyName)
|
protected virtual void SaveManyAggregateRoot(TEntity entity, string propertyName)
|
||||||
{
|
{
|
||||||
List<NativeTuple<Type, object>> insertLog = new List<NativeTuple<Type, object>>();
|
List<NativeTuple<Type, object>> insertLog = new List<NativeTuple<Type, object>>();
|
||||||
List<NativeTuple<Type, object, object, List<string>>> updateLog = new List<NativeTuple<Type, object, object, List<string>>>();
|
List<NativeTuple<Type, object, object, List<string>>> updateLog = new List<NativeTuple<Type, object, object, List<string>>>();
|
||||||
List<NativeTuple<Type, object>> deleteLog = new List<NativeTuple<Type, object>>();
|
List<NativeTuple<Type, object>> deleteLog = new List<NativeTuple<Type, object>>();
|
||||||
var stateKey = Orm.GetEntityKeyString(EntityType, entity, false);
|
var stateKey = Orm.GetEntityKeyString(EntityType, entity, false);
|
||||||
if (_states.TryGetValue(stateKey, out var state) == false) throw new Exception($"AggregateRootRepository 使用仓储对象查询后,才可以保存数据 {Orm.GetEntityString(EntityType, entity)}");
|
if (_states.TryGetValue(stateKey, out var state) == false) throw new Exception($"AggregateRootRepository 使用仓储对象查询后,才可以保存数据 {Orm.GetEntityString(EntityType, entity)}");
|
||||||
AggregateRootUtils.CompareEntityValueCascade(Orm, EntityType, state.Value, entity, propertyName, insertLog, updateLog, deleteLog);
|
AggregateRootUtils.CompareEntityValue(Orm, EntityType, state.Value, entity, propertyName, insertLog, updateLog, deleteLog);
|
||||||
AttachCascade(entity);
|
AttachAggregateRoot(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<TEntity> _dataEditing;
|
protected List<TEntity> _dataEditing;
|
||||||
@ -212,7 +212,7 @@ namespace FreeSql
|
|||||||
|
|
||||||
_statesEditing.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) =>
|
_statesEditing.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) =>
|
||||||
{
|
{
|
||||||
AggregateRootUtils.MapEntityValueCascade(Orm, EntityType, item, ov.Value);
|
AggregateRootUtils.MapEntityValue(Orm, EntityType, item, ov.Value);
|
||||||
ov.Time = DateTime.Now;
|
ov.Time = DateTime.Now;
|
||||||
return ov;
|
return ov;
|
||||||
});
|
});
|
||||||
@ -238,11 +238,11 @@ namespace FreeSql
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
_states[key] = state;
|
_states[key] = state;
|
||||||
AggregateRootUtils.CompareEntityValueCascade(Orm, EntityType, state.Value, item, null, insertLog, updateLog, deleteLog);
|
AggregateRootUtils.CompareEntityValue(Orm, EntityType, state.Value, item, null, insertLog, updateLog, deleteLog);
|
||||||
}
|
}
|
||||||
foreach (var item in _statesEditing.Values.OrderBy(a => a.Time))
|
foreach (var item in _statesEditing.Values.OrderBy(a => a.Time))
|
||||||
{
|
{
|
||||||
AggregateRootUtils.CompareEntityValueCascade(Orm, EntityType, item, null, null, insertLog, updateLog, deleteLog);
|
AggregateRootUtils.CompareEntityValue(Orm, EntityType, item, null, null, insertLog, updateLog, deleteLog);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
@ -12,7 +12,7 @@ using System.Reflection;
|
|||||||
|
|
||||||
static class AggregateRootUtils
|
static class AggregateRootUtils
|
||||||
{
|
{
|
||||||
public static void CompareEntityValueCascade(IFreeSql fsql, Type entityType, object entityBefore, object entityAfter, string navigatePropertyName,
|
public static void CompareEntityValue(IFreeSql fsql, Type entityType, object entityBefore, object entityAfter, string navigatePropertyName,
|
||||||
List<NativeTuple<Type, object>> insertLog,
|
List<NativeTuple<Type, object>> insertLog,
|
||||||
List<NativeTuple<Type, object, object, List<string>>> updateLog,
|
List<NativeTuple<Type, object, object, List<string>>> updateLog,
|
||||||
List<NativeTuple<Type, object>> deleteLog)
|
List<NativeTuple<Type, object>> deleteLog)
|
||||||
@ -28,7 +28,7 @@ static class AggregateRootUtils
|
|||||||
if (entityBefore != null && entityAfter == null)
|
if (entityBefore != null && entityAfter == null)
|
||||||
{
|
{
|
||||||
deleteLog.Add(NativeTuple.Create(entityType, entityBefore));
|
deleteLog.Add(NativeTuple.Create(entityType, entityBefore));
|
||||||
EachNavigateCascade(fsql, entityType, entityBefore, (path, tr, ct, stackvs) =>
|
NavigateReader(fsql, entityType, entityBefore, (path, tr, ct, stackvs) =>
|
||||||
{
|
{
|
||||||
deleteLog.Add(NativeTuple.Create(ct, stackvs.First()));
|
deleteLog.Add(NativeTuple.Create(ct, stackvs.First()));
|
||||||
});
|
});
|
||||||
@ -60,7 +60,7 @@ static class AggregateRootUtils
|
|||||||
switch (tbref.RefType)
|
switch (tbref.RefType)
|
||||||
{
|
{
|
||||||
case TableRefType.OneToOne:
|
case TableRefType.OneToOne:
|
||||||
CompareEntityValueCascade(fsql, tbref.RefEntityType, propvalBefore, propvalAfter, null, insertLog, updateLog, deleteLog);
|
CompareEntityValue(fsql, tbref.RefEntityType, propvalBefore, propvalAfter, null, insertLog, updateLog, deleteLog);
|
||||||
break;
|
break;
|
||||||
case TableRefType.OneToMany:
|
case TableRefType.OneToMany:
|
||||||
LocalCompareEntityValueCollection(tbref, propvalBefore as IEnumerable, propvalAfter as IEnumerable);
|
LocalCompareEntityValueCollection(tbref, propvalBefore as IEnumerable, propvalAfter as IEnumerable);
|
||||||
@ -91,7 +91,7 @@ static class AggregateRootUtils
|
|||||||
foreach (var item in collectionBefore as IEnumerable)
|
foreach (var item in collectionBefore as IEnumerable)
|
||||||
{
|
{
|
||||||
deleteLog.Add(NativeTuple.Create(elementType, item));
|
deleteLog.Add(NativeTuple.Create(elementType, item));
|
||||||
EachNavigateCascade(fsql, elementType, item, (path, tr, ct, stackvs) =>
|
NavigateReader(fsql, elementType, item, (path, tr, ct, stackvs) =>
|
||||||
{
|
{
|
||||||
deleteLog.Add(NativeTuple.Create(ct, stackvs.First()));
|
deleteLog.Add(NativeTuple.Create(ct, stackvs.First()));
|
||||||
});
|
});
|
||||||
@ -117,7 +117,7 @@ static class AggregateRootUtils
|
|||||||
{
|
{
|
||||||
var value = dictBefore[key];
|
var value = dictBefore[key];
|
||||||
deleteLog.Add(NativeTuple.Create(elementType, value));
|
deleteLog.Add(NativeTuple.Create(elementType, value));
|
||||||
EachNavigateCascade(fsql, elementType, value, (path, tr, ct, stackvs) =>
|
NavigateReader(fsql, elementType, value, (path, tr, ct, stackvs) =>
|
||||||
{
|
{
|
||||||
deleteLog.Add(NativeTuple.Create(ct, stackvs.First()));
|
deleteLog.Add(NativeTuple.Create(ct, stackvs.First()));
|
||||||
});
|
});
|
||||||
@ -133,20 +133,21 @@ static class AggregateRootUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (var key in dictBefore.Keys)
|
foreach (var key in dictBefore.Keys)
|
||||||
CompareEntityValueCascade(fsql, elementType, dictBefore[key], dictAfter[key], null, insertLog, updateLog, deleteLog);
|
CompareEntityValue(fsql, elementType, dictBefore[key], dictAfter[key], null, insertLog, updateLog, deleteLog);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static void EachNavigateCascade(IFreeSql fsql, Type rootType, object rootEntity, Action<string, TableRef, Type, List<object>> callback)
|
|
||||||
|
public static void NavigateReader(IFreeSql fsql, Type rootType, object rootEntity, Action<string, TableRef, Type, List<object>> callback)
|
||||||
{
|
{
|
||||||
Dictionary<Type, Dictionary<string, bool>> ignores = new Dictionary<Type, Dictionary<string, bool>>();
|
Dictionary<Type, Dictionary<string, bool>> ignores = new Dictionary<Type, Dictionary<string, bool>>();
|
||||||
var statckPath = new Stack<string>();
|
var statckPath = new Stack<string>();
|
||||||
var stackValues = new List<object>();
|
var stackValues = new List<object>();
|
||||||
statckPath.Push("_");
|
statckPath.Push("_");
|
||||||
stackValues.Add(rootEntity);
|
stackValues.Add(rootEntity);
|
||||||
LocalEachNavigate(rootType, rootEntity);
|
LocalNavigateReader(rootType, rootEntity);
|
||||||
ignores.Clear();
|
ignores.Clear();
|
||||||
|
|
||||||
void LocalEachNavigate(Type entityType, object entity)
|
void LocalNavigateReader(Type entityType, object entity)
|
||||||
{
|
{
|
||||||
if (entity == null) return;
|
if (entity == null) return;
|
||||||
if (entityType == null) entityType = entity.GetType();
|
if (entityType == null) entityType = entity.GetType();
|
||||||
@ -170,7 +171,7 @@ static class AggregateRootUtils
|
|||||||
statckPath.Push(prop.Name);
|
statckPath.Push(prop.Name);
|
||||||
stackValues.Add(propval);
|
stackValues.Add(propval);
|
||||||
callback?.Invoke(string.Join(".", statckPath), tbref, tbref.RefEntityType, stackValues);
|
callback?.Invoke(string.Join(".", statckPath), tbref, tbref.RefEntityType, stackValues);
|
||||||
LocalEachNavigate(tbref.RefEntityType, propval);
|
LocalNavigateReader(tbref.RefEntityType, propval);
|
||||||
stackValues.RemoveAt(stackValues.Count - 1);
|
stackValues.RemoveAt(stackValues.Count - 1);
|
||||||
statckPath.Pop();
|
statckPath.Pop();
|
||||||
break;
|
break;
|
||||||
@ -180,7 +181,7 @@ static class AggregateRootUtils
|
|||||||
statckPath.Push($"{prop.Name[idx++]}");
|
statckPath.Push($"{prop.Name[idx++]}");
|
||||||
stackValues.Add(val);
|
stackValues.Add(val);
|
||||||
callback?.Invoke(string.Join(".", statckPath), tbref, tbref.RefEntityType, stackValues);
|
callback?.Invoke(string.Join(".", statckPath), tbref, tbref.RefEntityType, stackValues);
|
||||||
LocalEachNavigate(tbref.RefEntityType, val);
|
LocalNavigateReader(tbref.RefEntityType, val);
|
||||||
stackValues.RemoveAt(stackValues.Count - 1);
|
stackValues.RemoveAt(stackValues.Count - 1);
|
||||||
statckPath.Pop();
|
statckPath.Pop();
|
||||||
}
|
}
|
||||||
@ -204,8 +205,7 @@ static class AggregateRootUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ConcurrentDictionary<Type, Action<IFreeSql, object, object>> _dicMapEntityValueCascade = new ConcurrentDictionary<Type, Action<IFreeSql, object, object>>();
|
public static void MapEntityValue(IFreeSql fsql, Type rootEntityType, object rootEntityFrom, object rootEntityTo)
|
||||||
public static void MapEntityValueCascade(this IFreeSql fsql, Type rootEntityType, object rootEntityFrom, object rootEntityTo)
|
|
||||||
{
|
{
|
||||||
Dictionary<Type, Dictionary<string, bool>> ignores = new Dictionary<Type, Dictionary<string, bool>>();
|
Dictionary<Type, Dictionary<string, bool>> ignores = new Dictionary<Type, Dictionary<string, bool>>();
|
||||||
LocalMapEntityValue(rootEntityType, rootEntityFrom, rootEntityTo);
|
LocalMapEntityValue(rootEntityType, rootEntityFrom, rootEntityTo);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user