예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
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);
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        /// <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);
            }
        }
예제 #6
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();

            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);
        }
예제 #7
0
        /// <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);
        }
예제 #8
0
        /// <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);
            }
        }
예제 #9
0
 void ITreeRepository.BatchInsert(IEnumerable entities, IEntity referEntity, EntityTreePosition position, Expression isolation)
 {
     BatchInsert(entities.Enumerable <TEntity>(), (TEntity)referEntity, position, (Expression <Func <TEntity> >)isolation);
 }
예제 #10
0
 void ITreeRepository.Insert(IEntity entity, IEntity referEntity, EntityTreePosition position, Expression isolation)
 {
     Insert((TEntity)entity, (TEntity)referEntity, position, (Expression <Func <TEntity> >)isolation);
 }
예제 #11
0
 /// <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);
 }
예제 #12
0
 /// <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);
 }
예제 #13
0
 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);
 }
예제 #14
0
 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);
 }
예제 #15
0
 void IEntityTreePersister.Move(IEntity entity, IEntity referEntity, EntityTreePosition position)
 {
     Move((TEntity)entity, (TEntity)referEntity, position);
 }
예제 #16
0
 void IEntityTreePersister.Insert(IEntity entity, IEntity referEntity, EntityTreePosition position)
 {
     Insert((TEntity)entity, (TEntity)referEntity, position);
 }