/// <summary> /// 检查是否需要移动。 /// </summary> /// <param name="entity"></param> /// <param name="referEntity"></param> /// <param name="position"></param> /// <returns></returns> private bool CheckNeedMove(TEntity entity, TEntity referEntity, EntityTreePosition position) { var bag1 = ParseEntityData(entity); if (referEntity == null) { return(bag1.Level != 1); } var bag2 = ParseEntityData(referEntity); var isBrotherly = IsBrotherly(bag1, bag2); if (isBrotherly) { //判断是否需要移动 if (position == EntityTreePosition.After && bag1.Order - bag2.Order == 1) { return(false); } if (position == EntityTreePosition.Before && bag2.Order - bag1.Order == 1) { return(false); } } //本来就属于它的孩子 else if (position == EntityTreePosition.Children && bag1.InnerId.StartsWith(bag2.InnerId) && bag1.InnerId.Length == bag2.InnerId.Length + metaTree.SignLength) { return(false); } return(true); }
/// <summary> /// 取参照实体的最大order值。 /// </summary> /// <param name="bag"></param> /// <param name="mode"></param> /// <param name="offset"></param> /// <param name="isolation"></param> /// <returns></returns> private int GetNewOrderNumber(EntityTreeUpdatingBag bag, EntityTreePosition mode, int offset = 0, Expression <Func <TEntity> > isolation = null) { if (bag == null) { return(GetNewOrderNumber(isolation)); } switch (mode) { case EntityTreePosition.Children: var sql = string.Format("SELECT MAX({0}) FROM {1} WHERE {2} LIKE {3}", GetOrderExpression(), DbUtility.FormatByQuote(syntax, metadata.TableName), QuoteColumn(metaTree.InnerSign), syntax.FormatParameter("pm")); var innerId = bag.InnerId; var parameters = new ParameterCollection { { "pm", innerId + new string('_', metaTree.SignLength) } }; return(database.ExecuteScalar((SqlCommand)sql, parameters).To <int>() + 1 + offset); case EntityTreePosition.Before: return(bag.Order + offset); case EntityTreePosition.After: return(bag.Order + 1 + offset); } return(0); }
/// <summary> /// 生成内码。 /// </summary> /// <param name="keyId"></param> /// <param name="order"></param> /// <param name="position"></param> /// <returns></returns> private string GenerateInnerId(string keyId, PropertyValue order, EntityTreePosition position) { var sOrder = order.ToString(); return(position == EntityTreePosition.Children || keyId.Length < metaTree.SignLength ? keyId + new string('0', metaTree.SignLength - sOrder.Length) + sOrder : GetPreviousKey(keyId) + new string('0', metaTree.SignLength - sOrder.Length) + sOrder); }
/// <summary> /// 将一个实体插入到参照实体的相应位置。 /// </summary> /// <param name="entity">插入的实体。</param> /// <param name="referEntity">参照的实体。</param> /// <param name="position">插入的位置。</param> public virtual void Insert(TEntity entity, TEntity referEntity, EntityTreePosition position) { Guard.ArgumentNull(entity, "entity"); var helper = CreatePersisterHelper(); helper.Insert(entity, referEntity, position); }
/// <summary> /// 将一个实体插入到参照实体的相应位置。 /// </summary> /// <param name="entity">插入的实体。</param> /// <param name="referEntity">参照的实体。</param> /// <param name="position">插入的位置。</param> /// <param name="isolation">数据隔离表达式。</param> public virtual void Insert(TEntity entity, TEntity referEntity, EntityTreePosition position = EntityTreePosition.Children, Expression <Func <TEntity> > isolation = null) { Guard.ArgumentNull(entity, nameof(entity)); if (referEntity == null) { var arg = CreateUpdatingArgument(entity); //获得新节点的Order值 arg.NewValue.Order = GetNewOrderNumber(null, EntityTreePosition.Children, 0, isolation); arg.NewValue.Level = 1; //生成新的InnerID arg.NewValue.FullName = arg.OldValue.Name; arg.NewValue.InnerId = GenerateInnerId(string.Empty, arg.NewValue.Order, EntityTreePosition.Children); UpdateEntityByArgument(entity, arg); repository.Insert(entity); return; } var arg1 = CreateUpdatingArgument(entity); var arg2 = CreateUpdatingArgument(referEntity); var keyId = arg2.OldValue.InnerId; //获得新节点的Order值 arg1.NewValue.Order = GetNewOrderNumber(arg2.OldValue, position); //获得参照节点的级别 arg1.NewValue.Level = arg2.OldValue.Level; //如果插入为孩子,级别则+1 if (position == EntityTreePosition.Children) { arg1.NewValue.Level += 1; } //生成新的InnerID arg1.NewValue.InnerId = GenerateInnerId(keyId, arg1.NewValue.Order, position); arg1.NewValue.FullName = GenerateFullName(arg1, arg2, position); UpdateEntityByArgument(entity, arg1); ValidationUnity.Validate(entity); try { repository.Insert(entity); //repository.Batch(brothers, (u, s) => u.Update(s)); } catch (Exception ex) { throw new EntityPersistentException(SR.GetString(SRKind.FailInEntityInsert), ex); } }
/// <summary> /// 生成内码。 /// </summary> /// <param name="keyId"></param> /// <param name="order"></param> /// <param name="position"></param> /// <returns></returns> private string GenerateInnerId(string keyId, PropertyValue order, EntityTreePosition position) { var sOrder = order.ToString(); if (metaTree.SignLength - sOrder.Length < 0) { throw new EntityTreeCodeOutOfRangeException("末级编码超出预设的" + metaTree.SignLength + "位编码。"); } return(position == EntityTreePosition.Children || keyId.Length < metaTree.SignLength ? keyId + new string('0', metaTree.SignLength - sOrder.Length) + sOrder : GetPreviousKey(keyId) + new string('0', metaTree.SignLength - sOrder.Length) + sOrder); }
/// <summary> /// 生成新的全名,以参考节点的全名作为基础 /// </summary> /// <param name="arg1"></param> /// <param name="arg2"></param> /// <param name="position"></param> /// <returns></returns> private string GenerateFullName(EntityTreeUpfydatingArgument arg1, EntityTreeUpfydatingArgument arg2, EntityTreePosition position) { var fullName = string.Empty; if (metaTree.Name == null || metaTree.FullName == null) { return(null); } //没有参考节点,则使用名称 if (arg2 == null) { fullName = arg1.NewValue.Name; } else { //获得参考节点的全名 fullName = arg2.NewValue.FullName; if (position != EntityTreePosition.Children) { //取前面一级的全名 fullName = GetPreviousFullName(fullName); } //拼接上当前的名称 fullName = string.Format("{0}{1}{2}", fullName, metaTree.NameSeparator, arg1.NewValue.Name); } return(fullName); }
/// <summary> /// 将一组实体插入到参照实体的相应位置。 /// </summary> /// <param name="entities">插入的实体集。</param> /// <param name="referEntity">参照的实体。</param> /// <param name="position">插入的位置。</param> /// <param name="isolation">数据隔离表达式。</param> public virtual void BatchInsert(IEnumerable <TEntity> entities, TEntity referEntity, EntityTreePosition position = EntityTreePosition.Children, Expression <Func <TEntity> > isolation = null) { if (referEntity == null) { var orderNo1 = GetNewOrderNumber(null, EntityTreePosition.Children, 0, isolation); foreach (var entity in entities) { var arg = CreateUpdatingArgument(entity); //获得新节点的Order值 arg.NewValue.Order = orderNo1++; arg.NewValue.Level = 1; //生成新的InnerID arg.NewValue.FullName = arg.OldValue.Name; arg.NewValue.InnerId = GenerateInnerId(string.Empty, arg.NewValue.Order, EntityTreePosition.Children); UpdateEntityByArgument(entity, arg); } repository.Batch(entities, (u, s) => u.Insert(s)); return; } var arg2 = CreateUpdatingArgument(referEntity); var keyId = arg2.OldValue.InnerId; var orderNo = GetNewOrderNumber(arg2.OldValue, position); foreach (var entity in entities) { var arg1 = CreateUpdatingArgument(entity); //获得新节点的Order值 arg1.NewValue.Order = orderNo++; //获得参照节点的级别 arg1.NewValue.Level = arg2.OldValue.Level; //如果插入为孩子,级别则+1 if (position == EntityTreePosition.Children) { arg1.NewValue.Level += 1; } //生成新的InnerID arg1.NewValue.InnerId = GenerateInnerId(keyId, arg1.NewValue.Order, position); arg1.NewValue.FullName = GenerateFullName(arg1, arg2, position); UpdateEntityByArgument(entity, arg1); } try { repository.Batch(entities, (u, s) => u.Insert(s)); } catch (Exception ex) { throw new EntityPersistentException(SR.GetString(SRKind.FailInEntityInsert), ex); } }
void ITreeRepository.BatchInsert(IEnumerable entities, IEntity referEntity, EntityTreePosition position, Expression isolation) { BatchInsert(entities.Enumerable <TEntity>(), (TEntity)referEntity, position, (Expression <Func <TEntity> >)isolation); }
void ITreeRepository.Insert(IEntity entity, IEntity referEntity, EntityTreePosition position, Expression isolation) { Insert((TEntity)entity, (TEntity)referEntity, position, (Expression <Func <TEntity> >)isolation); }
/// <summary> /// 将一个实体插入到参照实体的相应位置。 /// </summary> /// <param name="entity">插入的实体。</param> /// <param name="referEntity">参照的实体。</param> /// <param name="position">插入的位置。</param> /// <param name="isolation">数据隔离表达式。</param> public virtual void Insert(TEntity entity, TEntity referEntity, EntityTreePosition position = EntityTreePosition.Children, Expression <Func <TEntity> > isolation = null) { InsertAsync(entity, referEntity, position, isolation); }
/// <summary> /// 将一组实体插入到参照实体的相应位置。 /// </summary> /// <param name="entities">插入的实体集。</param> /// <param name="referEntity">参照的实体。</param> /// <param name="position">插入的位置。</param> /// <param name="isolation">数据隔离表达式。</param> public virtual void BatchInsert(IEnumerable <TEntity> entities, TEntity referEntity, EntityTreePosition position = EntityTreePosition.Children, Expression <Func <TEntity> > isolation = null) { BatchInsertAsync(entities, referEntity, position, isolation); }
async Task ITreeRepository.BatchInsertAsync(IEnumerable entities, IEntity referEntity, EntityTreePosition position, Expression isolation, CancellationToken cancellationToken) { await BatchInsertAsync(entities.Enumerable <TEntity>(), (TEntity)referEntity, position, (Expression <Func <TEntity> >) isolation, cancellationToken); }
async Task ITreeRepository.InsertAsync(IEntity entity, IEntity referEntity, EntityTreePosition position, Expression isolation, CancellationToken cancellationToken) { await InsertAsync((TEntity)entity, (TEntity)referEntity, position, (Expression <Func <TEntity> >) isolation, cancellationToken); }
void IEntityTreePersister.Move(IEntity entity, IEntity referEntity, EntityTreePosition position) { Move((TEntity)entity, (TEntity)referEntity, position); }
void IEntityTreePersister.Insert(IEntity entity, IEntity referEntity, EntityTreePosition position) { Insert((TEntity)entity, (TEntity)referEntity, position); }